2015-01-30 2 views
54

У меня есть библиотека, в которой есть статическое поле. Я хочу создать приложение и ссылаться на эту библиотеку, чтобы у меня было два экземпляра этого статического поля. .Net runtime не позволяет ссылаться на одну и ту же библиотеку дважды, но мне интересно, можно ли преодолеть это ограничение?Статический контекст всегда один в C#?

Мне не разрешено изменять библиотеку, но я могу ее скопировать/переименовать.

ответ

84

Это не так сумасшедший, как вы думаете. Фактически, вы можете достичь этого, используя AppDomains.

Каждый AppDomain имеет собственное хранилище для статических переменных. Таким образом, вы можете просто создать второй AppDomain в своем процессе и обмениваться данными между ними, используя объект, который наследуется от MarshalByRefObject, как в this MSDN example.

+3

Мне понравился ваш ответ, не могли бы вы предоставить некоторые сладкие LoC :) –

+0

@Jeremy [ссылка MSDN] (https://msdn.microsoft.com/en-us/library/system.appdomain.aspx) из моего В ответе есть полный пример подключения к домену через приложение, использующий прокси. –

+3

Это может быть не безумие *, но это наверняка вызывает немного «плохой архитектуры» для меня. – Falanwe

57

В то время как Lucas' suggestion на AppDomains будет работать, иначе вы можете создать этот эффект с помощью дженериков, поскольку класс с разными аргументами общего типа рассматривается как другой класс и поэтому имеет свои собственные статические поля.

public class SomeClass<T> 
{ 
    public static string SomeField; 
} 

Тогда:

SomeClass<int>.SomeField = "A"; 
SomeClass<string>.SomeField = "B"; 

Console.WriteLine(SomeClass<int>.SomeField); // A 
Console.WriteLine(SomeClass<string>.SomeField); // B 

Например, SomeClass<int> будет установлен в библиотеке, в то время как SomeClass<string> будет ваша копия. Конечно, это будет работать только в том случае, если вы можете изменить библиотеку или библиотеку, которая уже использовала дженерики.

+49

Это одно из самых красивых и ужасных злоупотреблений дженериками, которые я когда-либо видел. –

+2

@BradleyUffner подождать пока вы не увидите синглтоны CRTP в C++ – immibis

+3

Да, но это разные поля, а не два экземпляра одного и того же статического поля. –

1

Оба предложения должны работать, но все они потрясающе относятся к архитектуре.

Я не знаю об этом контексте, но в вашем случае можно просто создать класс агрегации с новым свойством, которое не является статическим и имеет только два экземпляра. Этот звук, как лучший способ для меня.

Каждый раз, когда у меня есть смарт-код, в голове появляется предупреждение. Смарт-код всегда слишком умен для разработчика.

+1

Я полностью осознаю последствия этого. Я объяснял, что в начале вопроса, но модератор удалил эту часть из-за оффтопика. У меня есть сторонняя библиотека, которую я не могу изменить, у меня есть необходимая мне функция дважды, но она статична, поэтому я могу использовать ее только один раз. Я спросил об этом создателя библиотеки, и его ответ заключался в том, чтобы попытаться использовать хаки, поскольку это слишком сложно переделать. Подход с двумя доменами работал хорошо, и он выглядит довольно легко и удобно (за исключением того, что вам нужно управлять пожизненным временем), поэтому я хорошо справляюсь с этим. – Archeg

+0

Но вы правы - важно указать, что вы не должны идти с таким подходом, если вам действительно не нужно – Archeg

Смежные вопросы