2016-05-16 3 views
7

私の最後のC#インタビューでは、
私はC#の文字列の不変性を証明するように頼まれた、私はc#文字列の不変性が何を意味しているのか知っていますが、コードを介してC#の文字列の不変性を証明することは可能ですか?サンプルコードスニペットをお願いします。 ありがとうございますC#で文字列の不変性を証明する方法は?

+1

両方の文字列オブジェクトのオブジェクト参照を確認してください。どちらも同じです。 – Marshal

+2

文字列を連結するループを作成して、GCが狂っているのを見て、あなたのアプリケーションがクレイジーのようにメモリを燃やすのを見ますか? – Nasreddine

+5

実際には、安全でないコードを使用して文字列を変更できることを実際に証明することはできません。あなたができることは、文字列が(CLR安全コードの文脈では)不変であることを約束する仕様を指し示すことです。あなたの仕事がプログラミングであれば、言語スペックを信頼することに慣れていなければなりません。もしその言語が仕様書のことをしなければ、それはコンパイラチームが修正するバグです。文字列が突然変異していないが、何も証明していない例を示すことができます。これが失敗する構造があるかもしれません。あなたが見つけるまで、あなたは単に仕様を信頼する必要があります。 –

答えて

5

あなたはからトピックに関する完全な記事を見つけることができます。これは、C#でのバグは別の問題であると見なされるべきかどうかを今

using System; 
using System.Runtime.InteropServices; 

namespace Demo 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      const string test = "ABCDEF"; // Strings are immutable, right? 
      char[] chars = new StringToChar {str = test}.chr; 
      chars[0] = 'X'; 

      // On an x32 release or debug build or on an x64 debug build, 
      // the following prints "XBCDEF". 
      // On an x64 release build, it prints "ABXDEF". 
      // In both cases, we have changed the contents of 'test' without using 
      // any 'unsafe' code... 

      Console.WriteLine(test); 

      // The following line is even more disturbing, since the constant 
      // string "ABCDEF" has been mutated too (because the interned 'constant' string was mutated). 

      Console.WriteLine("ABCDEF"); 
     } 
    } 

    [StructLayout(LayoutKind.Explicit)] 
    public struct StringToChar 
    { 
     [FieldOffset(0)] public string str; 
     [FieldOffset(0)] public char[] chr; 
    } 
} 

:私がやらなければならないことは、そのように、stringを変異させるいくつかのコードを示すことです。 :) (答えはおそらくFieldOffsetunsafeであると考えるべきであるさ - 。上記のコードは、うわさによればsafeであるためstringはmutatableすべきではない)

また、私はあなたがstringがで不変であることを正当に主張することができると思いますたとえ安全なコードでその不変性に違反するばかげたエッジケースがあったとしても、それは真実です。

+0

これはどのように証明されますか?その文字列は変更可能ですか?これは 'stringVariable + =" some string ";'のようなものと同じ概念ではありませんか?コードの最後の行を実行すると、コンパイラは 'stringVariable'の現在の値と指定した新しい文字列を単純に連結することはできません。代わりに新しい文字列オブジェクトを作成し、それを新しい連結文字列と同じに設定します。 –

+0

は文字列を可変オブジェクトとして宣言しましたが、これは文字列の不変性をどのように証明しますか?@ shamseer k smrは正解に答えました – samurai

+0

'FieldOffset'は' unsafe'でなければなりません。優れた例。 –

1

はい、ObjectIDGeneratorクラスを使用してC#ストリングの不変性を証明することは可能です。

後答えはC#でString Vs Stringbuilderにdotmobの記事から取られ

実はObjectIDGeneratorは、我々のprograms.Withに私たちがチェックすることができ、このクラスの助けを作成したインスタンスの一意の整数値を返します。新しいインスタンスは、次のプログラム.Consider文字列とStringBuilderの上のさまざまな操作のために作成されているかどうかを

using System; 
using System.Text; 
using System.Runtime.Serialization; 

class Program 
{ 
    static void Main(string[] args) 
    { 
    ObjectIDGenerator idGenerator = new ObjectIDGenerator(); 
    bool blStatus = new bool(); 
    //just ignore this blStatus Now. 
    String str = "My first string was "; 
    Console.WriteLine("str = {0}", str); 
    Console.WriteLine("Instance Id : {0}", idGenerator.GetId(str, out blStatus)); 
    //here blStatus get True for new instace otherwise it will be false 
    Console.WriteLine("this instance is new : {0}\n", blStatus); 
    str += "Hello World"; 
    Console.WriteLine("str = {0}", str); 
    Console.WriteLine("Instance Id : {0}", idGenerator.GetId(str, out blStatus)); 
    Console.WriteLine("this instance is new : {0}\n", blStatus); 
    //Now str="My first string was Hello World" 
    StringBuilder sbr = new StringBuilder("My Favourate Programming Font is "); 
    Console.WriteLine("sbr = {0}", sbr); 
    Console.WriteLine("Instance Id : {0}", idGenerator.GetId(sbr, out blStatus)); 
    Console.WriteLine("this instance is new : {0}\n", blStatus); 
    sbr.Append("Inconsolata"); 
    Console.WriteLine("sbr = {0}", sbr); 
    Console.WriteLine("Instance Id : {0}", idGenerator.GetId(sbr, out blStatus)); 
    Console.WriteLine("this instance is new : {0}\n", blStatus); 
    //Now sbr="My Favourate Programming Font is Inconsolata" 
    Console.ReadKey(); 
    } 
} 

の出力は、こののようになります。enter image description here

strが "Hello World"と連結されたときに、インスタンスIDが1から2に変更されました。一方、sbrのインスタンスIDは、追加操作後も3と同じです。これは、すべての不変性と不変性を示しています。 blStatus変数は、インスタンスが新規かどうかを示します。私はstringない不変であることを証明することができますhttp://dotnetmob.com/csharp-article/difference-string-stringbuilder-c/

+1

最初にチェックしてみましょう。正しい場合は答えを受け入れます –

+2

これは、テストする演算子とメソッドが新しい文字列インスタンスを作成することを証明しています。文字列が常に不変であることは証明されません。証明の意味を科学的に証明することがなぜ不可能であるかという質問の下にあるJのコメントを見てください。 –

+2

記事 – samurai

-2

簡単な例:

string str = "test";string str2 = str;Console.WriteLine(str2);

//出力:テスト

str = "DDD";Console.WriteLine(str2);

//出力:テスト

文字列が可変である場合には、このコードを試してみてください、 " str2 "は" DDD "でなければなりません。

関連する問題