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

Как отличить объект от типа, описанного классом Type?

У меня есть объект:

ExampleClass ex = new ExampleClass();

и

Type TargetType

Я хотел бы использовать ex для типа, описанного TargetType, следующим образом:

Object o = (TargetType) ex;

Но когда я это делаю, я получаю:

Тип или имя пространства имен 't' может не найдено

Итак, как это сделать? Я что-то здесь не хватает?

Update:

Я хотел бы получить что-то вроде этого:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

private otherClass;

И потому, что у меня будет много таких свойств, я хотел бы сделать это:

public CustomClass MyClassOuter
{
   get
   {
        return (GetThisPropertyType()) otherClass;
   }
}

private SomeOtherTypeClass otherClass;

Context:

Обычно в моем контексте в моем классе мне нужно создать много свойств. И каждый заменяет литье на тип свойства. Мне кажется, у меня нет смысла (в моем контексте), потому что я знаю, что такое тип возврата, и я хотел бы написать какой-то код, который будет делать кастинг для меня. Может быть, это случай дженериков, я пока не знаю.

Мне кажется, что я могу гарантировать в этом свойстве, что я получаю нужный объект и в правильном типе и на 100% способен передать его в тип свойства.

Все, что мне нужно сделать, так что мне не нужно указывать в каждом свойстве, что он должен "отличать значение до CustomClass", я хотел бы сделать что-то вроде "значение заливки в том же классе, что и это свойство".

Например:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (SpecialClass) MyInteralObjects["MyVeryOwnSpecialObject"];
      }
   }
}

И хорошо - я могу сделать много свойств, подобных этому выше, но есть две проблемы:

1) Мне нужно указать имя объекта в MyInternalObjects, но это то же самое, что и имя свойства. Это я решил с помощью System.Reflection.MethodBase.GetCurrentMethod(). Name.

2) В каждом свойстве мне нужно подвергать объект из MyInternalObjects различным типам. Например, в MyVeryOwnSpecialObject - в SpecialClass. Это всегда тот же класс, что и свойство.

Вот почему я хотел бы сделать что-то вроде этого:

class MYBaseClass
{
   protected List<Object> MyInternalObjects;
}

class MyClass
{
   public SpecialClass MyVeryOwnSpecialObject
   {
      get
      {
           return (GetPropertyType()) MyInteralObjects[System.Reflection.MethodBase.GetCurrentMethod().Name];
      }
   }
}

И теперь касается: Хорошо, зачем? Поскольку в моем приложении я буду иметь все преимущества безопасных типов и т.д. (Intellisense).

Второй: но теперь вы потеряете безопасность в этом месте? Нет. Потому что я очень уверен, что у меня есть объект моего типа в списке.

4b9b3361

Ответ 2

Object o = (TargetType) ex;

Этот код бесполезен. У вас может быть тип справа, но это все еще только объект с левой стороны. Вы не можете использовать функциональность, специфичную для TargetType, как это.


Так вы можете вызвать метод неизвестного объекта данного типа:

object myObject = new UnknownType();
Type t = typeof(UnknownType); // myObject.GetType() would also work
MethodInfo sayHelloMethod = t.GetMethod("SayHello");
sayHelloMethod.Invoke(myObject, null);

С помощью этого класса UnknownType:

class UnknownType
{
    public void SayHello()
    {
        Console.WriteLine("Hello world.");
    }
}

Ответ 3

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

Если это ссылочное преобразование, это означает, что фактическое значение (ссылка) останется неизменным. Все броски выполняют проверку, а затем копируют значение. Это не имеет никакого реального использования - вы можете выполнить проверку, используя Type.IsAssignableFrom вместо этого, и просто используйте неявный приведение к object, если вы хотите его в переменной типа object.

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

Что вы планируете делать с o после выполнения броска? Если вы можете это объяснить, мы можем попытаться объяснить, как добиться эффекта, который вам нужен.

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

РЕДАКТИРОВАТЬ: увидев ваше обновление, ваше свойство объявлено как возвращаемое CustomClass, поэтому все, что вам нужно, это:

public CustomClass MyClassOuter
{
   get
   {
        return (CustomClass) otherClass;
   }
}

Я подозреваю, что вы все еще не предоставили нам всю необходимую нам информацию. Это определенно, как будет определено ваше свойство, причем CustomClass является определенным типом? Почему вы пытались выполнить бросок динамически, когда знаете тип свойства?

EDIT: Похоже, вы просто пытаетесь сохранить некоторую типизацию - чтобы было проще вырезать и вставить. Не. Вы знаете тип во время компиляции, потому что вы знаете тип свойства во время компиляции (он указан в коде только несколькими строками выше). Используйте этот тип напрямую. Аналогичным образом не пытайтесь получить имя текущего метода для разработки ключа для использования. Просто введите имя напрямую. Опять же, вы знаете это во время компиляции, так почему бы быть динамичным? Я все на лень, когда это имеет смысл, но в этом случае это просто не так.

Ответ 4

Я не совсем уверен, что вы пытаетесь сделать, но впечатление, которое я получаю, заключается в том, что вы хотели бы иметь один экземпляр какого-либо объекта, который может "действовать как" много разных типов объектов, и вы хотите иметь геттеры, которые позволят вам легко просмотреть этот один объект различными способами. В этом случае я бы предложил создать один метод getter (а не свойство), например:

public T Get<T>()
{
   return (T)myObject;
}

Тогда вы бы назвали его так:

Foo foo = box.Get<Foo>();
Bar bar = box.Get<Bar>();
// etc...

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

public T Get<T>() where T : SomeBaseType

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

Это то, что вы имели в виду?

Ответ 5

if (ex is ExampleClass) 
{
  ExampleClass myObject = (ExampleClass)ex;
}

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