Подтвердить что ты не робот

Статические переменные и AppDomains, что происходит?

У меня

public static class A
{
   public static string ConnString;
}

[Serializable]
public class Test{
   // Accesing A 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"! ПОЧЕМУ???

этот код

TObj.ConnString = "NewDomainString"

предполагается изменить строку во вновь создаваемом домене, но, похоже, оба они ссылаются на один и тот же экземпляр!

Почему, что здесь происходит?

4b9b3361

Ответ 1

Существует только два способа доступа класса из другого AppDomain: один из них - это класс [Serializable], как ваш тестовый класс, другой - если класс наследуется от MarshalByRefObject. Поскольку ваш класс является Serializable, его копия создается для каждого вызова Cross-AppDomain. Итак, Test, что главный appdomain получает, когда вы вызываете...

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

на самом деле не экземпляр Test, который был создан в DomNew AppDomain, это копия, локальная для "основного" AppDomain, и поэтому ссылается на статические переменные из "основного" AppDomain.

Если вы хотите, чтобы Test отображал поведение, которое вы ожидаете, сделайте его наследуемым от MarshalByRefObject вместо Serializable.

Ответ 2

Вы отметили свой тестовый класс как Serializable. Это не верно. Вы должны были получить от MarshalByRef. В противном случае TObj будет просто локальной копией в текущем AppDomain.