2016-07-28 3 views
-5

ценит любую помощь ....Новичок C# - объект литья во время выполнения

Проблема: Выбор из трех различных типов, которые должен применяться во время выполнения, хочет иметь локальные переменный тип преобразуется в зависимости от результата.

Пример:

Object test; 

if (something == somethingElse) 
{ 
    test = VendorClass<VendorType> 
} 
else 
{ 
    test = OtherVendorClass<OtherVendorType> 
} 

Я посмотрел вокруг StackOverflow и нашел несколько хороших примеров, таких как

var newVar = (OtherVendorClass<OtherVendorType>)test; 

и

var newVar = test as OtherVendorClass<OtherVendorType>; 

Однако, все, что я видел так далеко не область тестовых переменных, просто создавайте новые локально.

Заранее спасибо.

+1

Не совсем понятно, что вы здесь просите; можете ли вы добавить более подробную информацию? –

+0

Как вы собираетесь использовать свой объект 'test' после кастинга? – Fabio

+0

Ничего себе .... похоже, я сделал что-то очень неправильно, глядя на отрицательные голоса. Может ли кто-нибудь посоветовать, где я ошибаюсь и сообщить? Спасибо – ma11achy

ответ

0

Вы можете сделать проверку типа на своем объекте, используя ключевое слово is.

if (myObject is MyFirstType) 
{ 
    MyFirstType obj = (MyFirstType)myObject; 
    obj.MyFirstTypeMethod(); 
} 
else if (myObject is MySecondType) 
{ 
    MySecondTypeobj = (MySecondType)myObject; 
    obj.MySecondTypeMethod(); 
} 
+0

Не рекомендуется это делать; в действительности вы бросаете объект дважды. Гораздо лучше попробовать «var foo = myObject как Foo;», тогда тест 'foo' не равен NULL. –

+0

Выполняете ли вы 'obj = (MyFirstType) myObject' или' myObject как MyFirstType', это ситуация, в которой вы не хотите быть. Это не правило 100% все время, но строго типизированный код должен быть написано так, что мы уже знаем, с каким типом мы имеем дело, и нам не нужно проверять объект, чтобы узнать, каков его тип. Нам не нужно знать тип * actual * - только интерфейс, который он реализует, или базовый класс, на который он наследует. Тогда преимущество в том, что мы можем работать с * известным * типом, даже не зная тип * actual *. –

1

Если вы спрашиваете, как изменить тип переменной test, ответ:

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

Вы можете выбрать тип для test, который является настолько общим, что он подходит для всех объектов, которые вы хотите вставить. Например, object.

object test; 
if (condition) 
    test = new VendorClass<VendorType>() 
else 
    test = new OtherVendorClass<OtherVendorType>() 

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

if(condition) 
    ((VendorClass<VendorType>)test).vendorMethod(); 
else 
    ((OtherVendorClass<OtherVendorType>)test).vendorMethod(); 

Более элегантное решение было бы, чтобы найти или определить другой тип, чем object, что является достаточно общим, чтобы держать все эти типы, но достаточно точным, чтобы иметь все свойства, необходимые для доступа.

Будучи «общим достаточно», что означает, что VendorClass<T> и OtherVendorClass<T> оба наследуются от него, но в этот момент я обращусь к руководству C# для Наследования. (https://msdn.microsoft.com/en-us/library/ms173149.aspx)

EDIT: Такой тип также может быть интерфейсом, реализуемым обоими типами. (https://msdn.microsoft.com/en-us/library/ms173156.aspx)

Также не стесняйтесь размещать ресурсы лучше, чем руководство C#, без сомнения, лучше объясняют наследование и интерфейсы в C#.

1

Проблема заключается в том, что если вы объявите переменную - test - и тогда эта переменная может содержать объект одного типа, другого типа или какого-либо другого типа, то что вы собираетесь делать с этим объектом? Вся суть строго типизированного языка заключается в том, что мы знаем тип каждого объекта, с которым мы работаем, или, по крайней мере, знаем что-то о его типе.

Если эти различные типы все реализовать некоторые общий интерфейс, то вы можете сделать это:

ISomeCommonInterface myObject = null; 

if(something == true) 
    myObject = new SomethingThatImplementsThatCommonInterface(); 
else 
    myObject = new SomethingElseThatImplementsThatCommonInterface(); 

Я не говорю, что это хорошая практика, но это работает. Идем дальше, вы знаете, что myObject является экземпляром ISomeCommonInterface. Таким образом, вы имеете дело с этим интерфейсом и не заботитесь о том, какова фактическая реализация.

(Это также работает, если типы наследуют от заявленного типа, или один объявленный тип и другие наследуют.)

В противном случае все, что вы могли бы сделать, это объявить переменную типа object. Теперь вы можете назначить любой тип, который вам нужен, но опять же, что побеждает цель сильной типизации. Мы всегда хотим, чтобы объект был отличен как некоторый известный предопределенный тип, чтобы мы знали, как его использовать или взаимодействовать с ним. Мы никогда не хотим иметь object, а затем реализуем «если это такой тип, вызовите этот метод, но если это тот тип, вызовите этот метод».

+0

Спасибо! Я узнал, что не делать :) – ma11achy

+1

Добро пожаловать! Как правило, что-то не так, если мы объявляем переменные как «объект», или если у нас есть объект, и мы пишем любой код, чтобы попытаться выяснить, каков его тип. (Ни один из них не является абсолютным, но они доставят вас далеко.) –

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