it-roy-ru.com

Как привести Object к его фактическому типу?

Если у меня есть:

void MyMethod(Object obj) {   ...   }

Как я могу привести obj к его фактическому типу?

87
Paul Lassiter

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

SomeType typed = (SomeType)obj;
typed.MyFunction();

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

  • отражение
  • реализация известного интерфейса
  • динамический

Например:

// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);

// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();

// dynamic
dynamic d = obj;
d.MyFunction();
144
Marc Gravell

Я не думаю, что вы можете (не без размышления), вы должны также предоставить тип для вашей функции:

void MyMethod(Object obj, Type t)
{
    var convertedObject = Convert.ChangeType(obj, t);
    ...
}

UPD:

Это может работать для вас:

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}
34
Maksim Vi.

Приведение к фактическому типу легко:

void MyMethod(Object obj) {
    ActualType actualyType = (ActualType)obj;
}
2
user1610694

В моем случае AutoMapper работает хорошо.

AutoMapper может отображать в/из динамических объектов без какой-либо явной конфигурации:

public class Foo {
    public int Bar { get; set; }
    public int Baz { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;

Mapper.Initialize(cfg => {});

var result = Mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);

dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);

Точно так же вы можете отобразить прямо из словарей на объекты, AutoMapper выровняет ключи с именами свойств.

дополнительная информация https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping

0
Soren

Приведите его к реальному типу, если вы, например, тип, он ориентирован из класса с именем abc . Вы можете вызвать вашу функцию следующим образом:

(abc)(obj)).MyFunction();

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

0
Masoud

Если ваш метод MyFunction() определен только в одном классе (и его потомках), попробуйте 

void MyMethod(Object obj) 
{
    var o = obj as MyClass;
    if (o != null)
        o.MyFunction();
}

Если у вас есть большое число в несвязанных классах, определяющих функцию, которую вы хотите вызвать, вы должны определить интерфейс и заставить ваши классы определять этот интерфейс:

interface IMyInterface
{
    void MyFunction();
}

void MyMethod(Object obj) 
{
    var o = obj as IMyInterface;
    if (o != null)
        o.MyFunction();
}
0
devio