6

NoStringInterningのデモンストレーションに問題があります

[assembly: System.Runtime.CompilerServices.CompilationRelaxations(System.Runtime.CompilerServices.CompilationRelaxations.NoStringInterning)]

    class Program
    {
        static void Main(string[] args)
        {
            String s1 = "Friday";
            String s2 = "Friday";
            String s3 = "Friday";
            String s4 = "Friday";
            String s5 = "Friday";
            String s6 = "Friday";
            String s7 = "Friday";
            String s8 = "Friday";
            String s9 = "Friday";
            // etc...
            Console.WriteLine(Object.ReferenceEquals(s1, s2));
            Console.WriteLine(Object.ReferenceEquals(s1, s3));
            Console.WriteLine(Object.ReferenceEquals(s1, s4));
            Console.WriteLine(Object.ReferenceEquals(s1, s5));
            Console.WriteLine(Object.ReferenceEquals(s1, s6));
            Console.WriteLine(Object.ReferenceEquals(s1, s7));
            Console.WriteLine(Object.ReferenceEquals(s1, s8));
            Console.WriteLine(Object.ReferenceEquals(s1, s9));
            // etc...

.NET CLR 2、3、4を試してみました。出力として、取得するのはTrueの束だけです。私はたくさんのFalseを期待しています!

4

3 に答える 3

7

ドキュメントには、次の属性が記載されています。

アセンブリを文字列リテラルのインターンを必要としないものとしてマークします。

つまり、コンパイラが文字列インターンを実行することを妨げることはなく、必要ではないというヒントを提供するだけです。この領域のドキュメントは少しまばらですが、これはこのMSDNフォーラムの投稿の結論でもあるようです。

于 2013-03-24T18:01:00.627 に答える
5

開いたドアを蹴るのではありませんが、明らかに属性はあなたが思っていることをしません。そのためのドキュメントは、MSDNとCLI仕様の両方で非常に貧弱です。CLR内での使用法から明らかなのは、CLRがオンになっている場合、コンパイラーは、モジュールレベルで同一の文字列がインターンされていることを確認するだけでよいということです。これには、インライン化、生成、および混合モードのアセンブリに関連する多くの副作用があります。

次に、モジュールとアセンブリの正確な違いを説明します。私にはできませんが、モジュールは奇妙な獣であり、一般的な.NETプログラミングでは実用的ではありません。この属性はまったく関係がないことを忘れてください。/ target:moduleオプションを指定してC#コンパイラを実行するカスタムビルドシステムがない限り、C#コンパイラは常にアセンブリレベルでインターンするため、テストでは常に「true」が生成されます。

于 2013-03-24T18:45:59.380 に答える
0

NoStringInterningのMSDNの説明によると

「アセンブリを文字列リテラルのインターンを必要としないものとしてマークします。」

アセンブリがインターンを必要としないと言うことは、機能をオフにする必要があると言うことと同じではありません。AFAIKそれを行う方法はありません(NGENを除く)。

于 2013-03-24T17:59:29.247 に答える