Hatena::ブログ(Diary)

当面C#と.NETな記録 このページをアンテナに追加 RSSフィード

2009/11/17 (火)

[] さよなら CAS  さよなら CAS - 当面C#と.NETな記録 を含むブックマーク  さよなら CAS - 当面C#と.NETな記録 のブックマークコメント

http://www.infoq.com/jp/news/2009/11/CAS-Replaced

CAS がなくなる件、InfoQ の記事になりましたね。

これってひょっとして unsafe の事実上の解禁になるのかな?よくわかってないですけど。

型安全はつまらないバグをかなり減らしてくれるんで、安易に unsafe に頼りたくないですが、これが解禁を意味するならうずうずしてしまう場面はありそうです(^^;

解禁じゃなかったらごめんなさい。記事の後半はよくわかりません…。

渋木宏明(ひどり)渋木宏明(ひどり) 2009/11/17 15:27 CAS と unsafe と型安全性は、全部別物ですよ ;-)

siokoshousiokoshou 2009/11/17 15:52 CAS がなくなって完全信頼になっても unsafe を使ったコードをさまたげる何かってあります?そこらへんがよくわからなくて…。

siokoshousiokoshou 2009/11/17 17:12 あれ、unsafe コードって特に何かに制限されてるわけじゃないようですね。
何かに制限されてるから事実上使えないのかとずっと思い込んでました…。はうっ

siokoshousiokoshou 2009/11/17 17:19 型安全が出てきたのは unsafe で型安全を壊せるって意味で出てきたんですが、文章が省略しすぎですね、すみません。

なちゃなちゃ 2010/01/07 17:09 unsafe つきでコンパイルすると、検証(コードのべりファイ)できないアセンブリになります。
※確か、べりファイしなくていいよってマークがつくイメージだったような気がします。

2009/11/12 (木)

[] string の IndexOf は .NET4 でもカルチャー依存のまま  string の IndexOf は .NET4 でもカルチャー依存のまま - 当面C#と.NETな記録 を含むブックマーク  string の IndexOf は .NET4 でもカルチャー依存のまま - 当面C#と.NETな記録 のブックマークコメント

昨日の記事は例が悪かったのでわんくまの中さんに正反対に誤読されて残念なので、わかりやすく一覧表にしてみました。

string の StartsWith, EndsWith, IndexOf, LastIndexOf のカルチャー依存/非依存(ordinal)の状況

.NET2〜3.5.1カルチャー依存
.NET4 CTPordinal
.NET4 beta1カルチャー依存 (元に戻した)
.NET4 beta2カルチャー依存
.NET4 正式版カルチャー依存 (たぶん)

CTP ではセキュアな変更を行ったものの、互換性のために beta1 以降元に戻されました。

BCL チームによると

UPDATE for .NET 4 Beta 1 In order to maintain high compatibility between .NET 4 and previous releases, we have decided to revert this change. The behavior of String's default partial matching overloads and String and Char's ToUpper and ToLower methods now behave the same as they did in .NET 2.0/3.0/3.5. The change back to the original behavior is present in .NET 4 Beta 1. We apologize for any interim confusion this may cause. We continue to recommend being explicit about the string comparison behavior you want, by always specifying a StringComparison value for the methods on String that accept it.

http://blogs.msdn.com/bclteam/archive/2008/11/04/what-s-new-in-the-bcl-in-net-4-0-justin-van-patten.aspx

だそうです。

ちなみに Silverlight3 は ordinal です。

そしてもう一度書いておくと、BCL Team 曰く「StringComparison パラメータをとるオーバーロードが存在するときはいつでも、このパラメータをとらないオーバーロードの代わりにそれを使ってください。それは、あなたのコードをより明白で維持するのをより簡単にします。」だそうです。

推奨事項は http://blogs.msdn.com/bclteam/archive/2005/06/01/424012.aspx

また、FxCop が指摘してくれるので使うことをおすすめします。

何が危ないの?って問題は昨日の記事を読んでください。

この問題とは別に〇の問題などが修正されているようです。

2009/11/11 (水)

[] あなたがやりたいことはきっと "Hoge".IndexOf( "Hoge" ) ではなく "Hoge".IndexOf( "Hoge", StringComparison.Ordinal )  あなたがやりたいことはきっと "Hoge".IndexOf( "Hoge" ) ではなく "Hoge".IndexOf( "Hoge", StringComparison.Ordinal ) - 当面C#と.NETな記録 を含むブックマーク  あなたがやりたいことはきっと "Hoge".IndexOf( "Hoge" ) ではなく "Hoge".IndexOf( "Hoge", StringComparison.Ordinal ) - 当面C#と.NETな記録 のブックマークコメント

ずいぶん前にも書きましたが string の IndexOf には罠があります。ただ単に IndexOf( "Hoge" ) と書くと IndexOf( "Hoge", StringComparison.CurrentCulture ) の動作をしてしまいます。きっとあなたがやりたいことは IndexOf( "Hoge", StringComparison.Ordinal ) だと思います。

.NET4 で、この文字列の危険な落とし穴を修正しようとしたようですが、結局変更はキャンセルされたようです。BCL Team Blog によると、CTP では StartsWith, EndsWith, IndexOf, LastIndexOf をカルチャー依存から非依存(ordinal)に変更したけど、β1で戻したよとあります。実現していれば大きな影響を与えただけに反対されたのでしょうか?

変更しようとした理由はセキュリティへの懸念で、開発者が気づかずにカルチャー依存の文字列比較を行ってしまうことを防ごうとしたようです。これやばいんじゃね?とタレこんだけど使い方次第だと却下された私としては変更して欲しかったのですが、実現ならずで残念です。でも、BCL チームが変更しようとしたということは、やはり危険だと強く認識してるってことなので、無駄じゃなかったのかなとちょっと報われた気持ちです(私のタレこみがきっかけかどうかはわかりませんが)。

もう一度 IndexOf で遊んでみます。@IT 会議室の @echo さんの例を試してみます。「〇」は漢数字の零です。

using System;

class P
{
  static void Main()
  {
    Console.WriteLine( "AA".IndexOf("〇A") );           // 0
    Console.WriteLine( "AA".IndexOf("〇") );             // 0
    Console.WriteLine( "A〇A".IndexOf("AA") );         // 0
    Console.WriteLine( "〇A〇A".IndexOf("AA") );       // 1
    Console.WriteLine( "〇A〇A".IndexOf("〇A") );       // 1
    Console.WriteLine( "〇A〇A".LastIndexOf( "〇A" ) ); // 3
    Console.WriteLine();

    Console.WriteLine( "AA".IndexOf( "〇A", StringComparison.Ordinal ) );         // -1
    Console.WriteLine( "AA".IndexOf( "〇", StringComparison.Ordinal ) );           // -1
    Console.WriteLine( "A〇A".IndexOf( "AA", StringComparison.Ordinal ) );       // -1
    Console.WriteLine( "〇A〇A".IndexOf( "AA", StringComparison.Ordinal ) );     // -1
    Console.WriteLine( "〇A〇A".IndexOf( "〇A", StringComparison.Ordinal ) );     // 0
    Console.WriteLine( "〇A〇A".LastIndexOf( "〇A", StringComparison.Ordinal ) ); // 2

    Console.ReadKey();
  }
}

右側に書いた結果は Windows7/.NET3.5.1 での実行結果です。@echo さんの当時の実行結果と違いますが、やはりおかしいのは一緒です。どうしてこうなるのかわかりません。Ordinal での比較は OK ですね。@IT 会議室にめーさんが投稿したきっかけはカルチャー依存比較で無限ループするという問題でした。ソースコードは一見正常に見えるので、カルチャー依存がデフォルトなのは、問題が起きるまで気付かないタイプのいやらしい問題を産むということがわかります。怖いですね。

でもまあ FxCop が指摘してくれるので、使うことをおすすめします。

BCL Team 曰く「StringComparison パラメータをとるオーバーロードが存在するときはいつでも、このパラメータをとらないオーバーロードの代わりにそれを使ってください。それは、あなたのコードをより明白で維持するのをより簡単にします。」だそうです。recommend

でも、忘れちゃうんだよね…。やっぱり変えて欲しいんだけどなぁ…。

(追記) Silverlight で試してみると、ややこしいことにカルチャーに依存しない動作がデフォルトでした。つまり、"Hoge".IndexOf( "Hoge" ) が "Hoge".IndexOf( "Hoge", StringComparison.Ordinal ) の動作と同じです。

それはそれでいいんですが(ややこしいけど)、VisualStudio 2010 beta2 で試してみるとカルチャーに依存しない動作をしました…。どーなってるんだ…。

(追記2) aetos さんからのコメントによると、.NET4 Beta2 の IndexOf はカルチャー依存で、〇のおかしな挙動が修正されたとのことです。おそらく .NET4 が Unicode 5.1 準拠になった影響と思いますが詳しいことはわかりません。

aetos さんの濁点のテストを Silverlight でやってみると、やはり Silverlight の IndexOf は Ordinal でした。そして、StringComparison.CurrentCulture を明示した場合は一致と判断されました。

egtraegtra 2009/11/11 10:41 変更が無理なら、いっそStringComparisonを引数に取らないものにObsoleteAttributeでも付けたらどうなのでしょうかという気がしてきますね。

siokoshousiokoshou 2009/11/11 11:09 ですよねー、まったくです。

aetosaetos 2009/11/11 16:22 Beta2 では、上記のコードは CurrentCulture を明示しても Ordinal と同じ結果になります。
"が".IndexOf("か゛") は 0 となり、"が".IndexOf("か゛", StringComparison.Ordinal) は -1 になります。
MSDN にはやっぱりカルチャー依存って書いてあります。
http://msdn.microsoft.com/ja-jp/library/k8b1470s(VS.100).aspx

Ordinalになったのではなく、CurrentCulture のバグが修正されたような気がします。
Win7 なのも関係している?

siokoshousiokoshou 2009/11/11 20:00 おお、なるほどー、そういうことなんですね!
Win7の影響か、もしくは .NET4 が Unicode 5.1 準拠になった影響か、そこらへんっぽいですね。
すっきりしました、どうもありがとうございます(^^)

2009/10/25 (日)

[] CAS はやめちゃうそうです  CAS はやめちゃうそうです - 当面C#と.NETな記録 を含むブックマーク  CAS はやめちゃうそうです - 当面C#と.NETな記録 のブックマークコメント

http://blogs.msdn.com/shawnfa/archive/2009/06/12/clr-v4-security-policy-roundup.aspx

.NET4 のセキュリティは簡単にするとは聞くものの、じゃあどうなるの?ってところを聞いたことがなかったのでメモしておきます。

難しい上に意味がない CAS はやめて、砂場だけ残すようです。ちゃんと読んでないので以上。5ヵ月後に日本語情報が出たらそれを読もうかな程度の関心しかないもので…。

2009/10/17 (土)

[] コード公開  コード公開 - 当面C#と.NETな記録 を含むブックマーク  コード公開 - 当面C#と.NETな記録 のブックマークコメント

http://referencesource.microsoft.com/netframework.aspx

Dotnetfx_4016_VistaSP2

Dotnetfx_35.1_Win7

出た!

久しぶりに .NET の中のコードにステップインできるようになった。なんだかすごくうれしい。

関連 http://d.hatena.ne.jp/siokoshou/20090824

2005 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 11 | 12 |
2006 | 01 | 02 | 03 | 04 | 06 | 09 | 11 | 12 |
2007 | 02 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2008 | 01 | 02 | 03 | 04 | 05 | 06 | 08 | 09 | 10 | 12 |
2009 | 01 | 03 | 04 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2010 | 07 |
2011 | 04 | 07 | 10 |
2012 | 04 | 12 |
2013 | 08 |
2014 | 03 | 08 |
2017 | 09 |