静态变量实例和AppDomains,发生了什么?

时间:2012-03-21 14:14:03

标签: c# variables static instance appdomain

我有

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"
}

但不!两个WriteLines,打印出相同的值“NewDomainString”! WHY ???

此代码

TObj.ConnString = "NewDomainString"

应该更改新创建的域中的字符串,但似乎它们都引用同一个实例!

为什么,这里发生了什么?

2 个答案:

答案 0 :(得分:22)

只有两种方法可以从另一个AppDomain访问一个类 - 一个是类[Serializable],一个是Test类,另一个是类是否继承自MarshalByRefObject。因为您的类是Serializable,所以会为每个跨AppDomain调用创建一个副本。因此,当您致电时,主appdomain会获得Test ...

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

实际上不是在“DomNew”AppDomain中创建的Test实例 - 它是“main”AppDomain的本地副本,因此引用“main”AppDomain中的静态变量。

如果您希望Test展示您期望的行为,请将其从MarshalByRefObject继承而不是Serializable。

答案 1 :(得分:12)

您将Test类标记为Serializable。这是错的。你应该从MarshalByRef派生出来。否则,TObj将只是当前AppDomain中的本地副本。