如果我有:
void MyMethod(Object obj) { ... }
如何将
obj
转换为其实际类型?
如果您知道实际类型,那么只需:
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();
我认为你不能(不是没有反思),你也应该为你的函数提供一个类型:
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<SomeType>(object.ToString());
您还可以使用模式匹配
void MyMethod(Object obj) {
if(obj is SomeType myVar){
myVar.MyFunction();
}
}
如果您的
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();
}
就我而言,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
另一种选择是将其序列化,然后将其反序列化为您想要的对象。
JsonConvert.DeserializeObject<OtherType>(JsonConvert.SerializeObject(obj));
我建立在@Maksim Vi.的回答之上:
var convertedObject = Convert.ChangeType(someObject, someObject.GetType());
这回答了最初的问题,但不是调用方法的意图。如果您只需要转换为其实际类型,那么这是可行的。
要调用方法,您可以执行前面提到的操作:
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);
上述某些解决方案对我不起作用的原因是因为我通过 API 客户端传递对象,并且模型未在新应用程序中加载(库版本降级问题等目前无法解决)。这就是我解决这个问题的方法:
var obj= ...code for assigning to the object...
var newObj = JsonConvert.DeserializeObject<ObjectType>(JsonConvert.SerializeObject(obj));
附注为此,我们需要使用 Newtonsoft.Json 库。
如果您现在的类型例如是从名为 abc 的类定向的,请将其转换为其真实类型。 您可以通过这种方式调用您的函数:
(abc)(obj)).MyFunction();
如果您不知道该功能,可以通过其他方式完成。总是不容易。但你可以通过它的签名以某种方式找到它。如果您遇到这种情况,请告诉我们。
如果可能有多种类型,方法本身不知道要转换的类型,但调用者知道,你可以使用这样的东西:
void TheObliviousHelperMethod<T>(object obj) {
(T)obj.ThatClassMethodYouWantedToInvoke();
}
// Meanwhile, where the method is called:
TheObliviousHelperMethod<ActualType>(obj);
可以使用括号后的
where
关键字添加对类型的限制。
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 );
}
转换为实际类型很容易:
void MyMethod(Object obj) {
ActualType actualyType = (ActualType)obj;
}