none
casting an object RRS feed

  • Вопрос

  • I want to cast an object that I have created from a typename to the
    corresponding type. Can anycone tell me how to do this?

    //Here, Create the object of type "MyClass"
    object obj=Activator.CreateInstance(strAssemblyName, "MyClass");
    //Now, I want to do something like ((MyClass)obj).Method
    //Can I do this?

    • Перемещено Siddharth Chavan 1 октября 2010 г. 22:48 MSDN Forums Consolidation (От:Visual C#)
    21 января 2010 г. 16:52

Ответы

  • Критикую - var - это тот же object в вашем случае - тип, выведенный из объявления Invoke(). Поэтому ваш код аналогичен обчыному
    object castedObject = obj;

    Вы исходите из предположения что каст - это операция, которая выполняется. На самом деле каст - это указание компилятору на настоящий тип объекта. a = (A)b просто копирует ссылку на объект из переменной b в переменную a. После компиляции оно превращается в a = b.

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

    Если во время компиляции вы не знаете о типе MyClass, то нет никакого способа написать в коде obj.MethodDefinedInMyClass. Компилятор не знает о MyClass, не знает о его методах, и никакие касты и пляски с генериками не заставят его проглотить неизвестный метод.

    - Используйте reflection
    - Дождитесь C# 4.0 и динамиков
    - Перейдите на VB.NET, там уже давно есть динамики
    - Выделите интерфейс из MyClass в IMyClass, сделайте так, чтобы интерфейс был известен во время компиляции. Кастуйте к интерфейсу.

    • Предложено в качестве ответа I.Vorontsov 25 января 2010 г. 12:18
    • Помечено в качестве ответа I.Vorontsov 26 января 2010 г. 5:58
    24 января 2010 г. 12:37

Все ответы

  • if(obj is MyClass)
    {
        ((MyClass)obj).Method();
    }

    или

    MyClass mc = obj as MyClass;
    if(mc != null)
    {
        mc.Method();
    }

    • Предложено в качестве ответа I.Vorontsov 22 января 2010 г. 13:59
    • Отменено предложение в качестве ответа Suranov Dmitry 22 января 2010 г. 15:36
    21 января 2010 г. 17:53
  • Не могу принять это в качестве решения.
    Чтобы использовать рефлексию и работать с заранее неизвестными типами это решение не годится.
    разумеется что если я могу предположить что за тип мне может прийти то достаточно сделать как вы сказали.
    22 января 2010 г. 15:41
  • С заранее неизвестными типами нет смысла кастовать. Зачем каст, если вы не можете объявить переменную "заранее неизвестного" типа?
    Если вам просто нужно вызвать метод по имени - достаньте его из типа объекта, через  obj.GetMethod(name).Invoke(obj, ...)
    22 января 2010 г. 20:45
  • Или используйте язык который поддерживает late binding, например VB.
    This posting is provided "AS IS" with no warranties, and confers no rights.
    23 января 2010 г. 18:58
    Модератор
  • нашел идею для решения в другой ветке. 
    Тема в том чтобы сначала испольщовать дженерик метод а потом сделть на него ссылку использую рефлексию.

    public static T Cast<T>(object o)
    {
    return (T)o;
    }
    Then invoke this using reflection:

    MethodInfo castMethod = this.GetType().GetMethod("Cast").MakeGenericMethod(t);
    var castedObject = castMethod.Invoke(null, new object[] { obj });                           
    // в оригинале использовалось не var а  object, но это было бесперспективно, на мой взгляд

    Покритикуйте, пожалуйста
    24 января 2010 г. 9:12
  • Критикую - var - это тот же object в вашем случае - тип, выведенный из объявления Invoke(). Поэтому ваш код аналогичен обчыному
    object castedObject = obj;

    Вы исходите из предположения что каст - это операция, которая выполняется. На самом деле каст - это указание компилятору на настоящий тип объекта. a = (A)b просто копирует ссылку на объект из переменной b в переменную a. После компиляции оно превращается в a = b.

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

    Если во время компиляции вы не знаете о типе MyClass, то нет никакого способа написать в коде obj.MethodDefinedInMyClass. Компилятор не знает о MyClass, не знает о его методах, и никакие касты и пляски с генериками не заставят его проглотить неизвестный метод.

    - Используйте reflection
    - Дождитесь C# 4.0 и динамиков
    - Перейдите на VB.NET, там уже давно есть динамики
    - Выделите интерфейс из MyClass в IMyClass, сделайте так, чтобы интерфейс был известен во время компиляции. Кастуйте к интерфейсу.

    • Предложено в качестве ответа I.Vorontsov 25 января 2010 г. 12:18
    • Помечено в качестве ответа I.Vorontsov 26 января 2010 г. 5:58
    24 января 2010 г. 12:37