Если бы у меня был:
void MyMethod(Object obj) { ... }
Как я могу привести obj
его к фактическому типу?
obj.MyFunction();
не компилируется, хотя я знаю, что у реального объекта есть эта функция.
MyFunction
метод?
Если бы у меня был:
void MyMethod(Object obj) { ... }
Как я могу привести obj
его к фактическому типу?
obj.MyFunction();
не компилируется, хотя я знаю, что у реального объекта есть эта функция.
MyFunction
метод?
Ответы:
Если вы знаете фактический тип, просто:
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();
as
для приведения типов и type(of: ClassName)
функция для проверки типа экземпляра.
Я не думаю, что вы можете (не без размышлений), вы также должны указать тип своей функции:
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;
...
}
}
Как насчет JsonConvert.DeserializeObject (object.ToString ());
var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
В моем случае 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
Этот метод может быть не самым эффективным, но он прост и выполняет свою работу.
Он выполняет две операции: сначала он вызывает .ToString (), который в основном представляет собой сериализацию, а затем десериализацию с использованием Newtonsoft nuget (который вы должны установить).
public T Format<T>(Object obj) =>
JsonConvert.DeserializeObject<T>(obj.ToString());
Если ваш 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();
}
Приведите его к его реальному типу, если вы теперь используете тип, например, он ориентирован из класса с именем abc. Вы можете вызвать свою функцию таким образом:
(abc)(obj)).MyFunction();
если вы не знаете функцию, это можно сделать по-другому. Не всегда просто. Но каким-то образом его можно найти по подписи. Если это ваш случай, сообщите нам об этом.
Приведение к фактическому типу очень просто:
void MyMethod(Object obj) {
ActualType actualyType = (ActualType)obj;
}
Implement an interface to call your function in your method
interface IMyInterface
{
void MyinterfaceMethod();
}
IMyInterface MyObj = obj as IMyInterface;
if ( MyObj != null)
{
MyMethod(IMyInterface MyObj );
}