Вызовите интерфейс, используя имя переменной - PullRequest
2 голосов
/ 27 декабря 2011

Я назначаю имя интерфейса в переменной, через эту переменную мне нужно вызвать интерфейс, т.е. в классе ChannelFactory принимать только интерфейс. Если я непосредственно указываю интерфейс как Test в ChannelFactory, то он работает нормально.

 string interfaceName = "Test";
 var factory = new ChannelFactory<**interfaceName**>(new BasicHttpBinding(), new EndpointAddress(*********));

Пожалуйста, предложите возможный способ, как привести тип из строковой переменной к интерфейсу.

Ответы [ 4 ]

5 голосов
/ 27 декабря 2011

Вы не можете напрямую привести тип из строковой переменной к интерфейсу.Однако вы можете использовать отражение для создания универсального типа.

Имейте в виду, однако, что получающаяся фабрика будет иметь тип объекта, поэтому вызов всех интерфейсных методов на ней также должен быть выполнен с помощью отражения (или с помощью динамическое ключевое слово)

Следующий код создаст отражение в канале ChannelFactory, но, как вы видите, результат имеет тип объекта, то есть вы не можете напрямую вызывать методы канала для него.

string interfaceName = "StackOverflow.ITest";

Type f = typeof (ChannelFactory<>);
Type[] typeargs = {Type.GetType(interfaceName, true)};

Type constructed = f.MakeGenericType(typeargs);
object factory = Activator.CreateInstance(constructed);
1 голос
/ 27 декабря 2011

Нельзя передать interfaceName как строку в общем ограничении. Вы можете сделать ниже

string interfaceName = "Test";
Type myInterfaceType = Type.GetType(interfaceName);
var factoryType = typeof(ChannelFactory<>).MakeGenericType(myInterfaceType);
var factoryCtr = factoryType.GetConstructor(new []{ typeof(Binding), typeof(EndpointAddress)});
ChannelFactory factory = factoryCtr.Invoke(new object[]{ new BasicHttpBinding(), new EndpointAddress("")}) as ChannelFactory;
1 голос
/ 27 декабря 2011

Прежде всего: вы не можете этого сделать! Ваша строка кода

var factory = new ChannelFactory<interfaceName>(new BasicHttpBinding(), new EndpointAddress(***));

может указывать на то, что фабрика (типа var) является вариантом , но это не так.Это переменная, и она безопасна от типа, сделана компилятором благодаря универсальному вызову new ChannelFactory<interfaceName>.Таким образом, вы не можете указать переменный интерфейс в общем вызове там.

0 голосов
/ 27 декабря 2011

Для продолжения ответа Фишермэна, во-вторых, , вы также не можете этого сделать!

Список аргументов типа универсального типа (имена типов в угловых скобках; дляНапример, int в List<int>) не являются переменными .Это статические токены времени компиляции.Вы не можете сделать это больше, чем то, что вы пытаетесь сделать:

string className = "FileInfo";
**className** theObject = new **className**("C:\\autoexec.bat");

Поскольку C # - статически типизированный язык, типы, обозначаемые токенами name-name, должны быть статически известны во время компиляции.Обратите внимание, что ответы на основе рефлексии здесь оставляют вас со ссылкой, статический тип которой является подтипом ChannelFactory<TChannel>, не являющимся типичным ChannelFactory или object.У вас не может быть статической ссылки во время компиляции на тип, который будет известен только во время выполнения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...