2012-03-21 10 views
21

私は静的変数インスタンスとAppDomains、何が起こっていますか?

public static class A 
{ 
    public static string ConnString; 
} 

[Serializable] 
public class Test{ 
    // Accesing A's field; 
    public string ConnString{get{return A.ConnString;}set{A.ConnString=value;}} 
} 

void Main() 
{ 
    A.ConnString = "InitialString"; // I set A.ConnString in the current domain 

    var newDomain = AppDomain.CreateDomain("DomNew"); 
    Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test ; 

    TObj.ConnString = "NewDomainString"; // It is supposed to set A.ConnString in the newDomain aka a different instance of A.ConnString 

    // Here it is supposed to print two different values 
    Console.WriteLine(A.ConnString); // "InitialString" 
    Console.WriteLine(TObj.ConnString); // "NewDomainString" 
} 

を持っている。しかしNO! 2つのWriteLinesは、同じ値 "NewDomainString"を出力します! WHY ???

このコード

TObj.ConnString = "NewDomainString" 

は、新しく作成されたドメイン内の文字列を変更することになったが、彼らの両方が同じインスタンスを参照するようです!

なぜ、ここで何が起こっていますか?

+6

可能性のある複製http://stackoverflow.com/questions/4298913/static-fields-in-appdomain – daryal

+2

タイトルに「C#」などのプレフィックスを付けないでください。それはタグのためのものです。 –

+0

あなたは正しいジョンです!初心者ここ:)私は学んでいる!ありがとう! –

答えて

21

クラスが別のAppDomainからアクセスできる2つの方法があります.1つは、クラスが[Serializable]であり、Testクラスであるから、もう1つはMarshalByRefObjectから継承する場合です。あなたのクラスはSerializableなので、AppDomainを呼び出すたびにそのコピーが作成されます。だから、あなたが呼び出すときに、メインのAppDomainが得ることTest ...

Test TObj = newDomain.CreateInstanceAndUnwrap(typeof(Test).Assembly.FullName, typeof(Test).FullName) as Test; 

は、それが「メイン」のAppDomainにローカルコピーであるAppDomain-実際に「DomNew」で作成されたテストのインスタンスではなく、したがって、 "メイン" AppDomainから静的変数を参照します。

Testに期待する動作が表示されるようにするには、シリアル化可能ではなくMarshalByRefObjectから継承させます。

+1

Nit:実際には3番目の方法があります。出血によってマーシャルhttp://www.bluebytesoftware.com/blog/PermaLink,guid,884ca8af-76fb-4753-a9d9-d12075dabb51​​.aspx – JaredPar

+0

@JaredPar yikes、yeah ...私は憂鬱になる。 –

+0

Thanx、それは実際に私が探していたものでした。私は質問をした直後に自分自身で答えを見つけました。何らかの理由で私はMarshalByRef継承を試みなかったが、そのようなことがあることは分かっていた。私はこれらの2つの方法(Serializable AttributeとMarshalByRef継承)が同じであると言っている別のフォーラムの答えによって、私が誤解していたと思います。 Serializable Attirbuteがクラスの "ローカル"コピーを作成する方法であれば、実際に別のドメインのオブジェクトにアクセスするのではないでしょうか?オブジェクトの状態を別のドメインから「読み取る」だけですか? –

12

TestクラスをSerializableとしてマークしました。これは間違っています。 MarshalByRefから派生しているはずです。それ以外の場合、TObjは現在のAppDomainのローカルコピーになります。

+0

そうです:)感謝の男! –

関連する問題