Якщо я маю:
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 (який потрібно встановити).
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 );
}