首页 > 解决方案 > 通过 GetType 投射到对象?

问题描述

简化:

我们有自己的从 SqlDataReader 到实体的数据库映射器。

在正常情况下,情况是这样的:

void Main()
{
    object s = (int?)1;
    MyClass newObjectToReturn = Activator.CreateInstance<MyClass>();
    typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { s });



}
class MyClass
{
    public int? MyProperty { get; set; }
}

值得一提的是,这条线:

object s = (int?)1;

这里是为了模拟将值包装为 Object 的 SqlDataReader。在调试中,我认为它是Object{int}

一切正常,工作正常。

那么问题出在哪里?

问题是 DB 中的类型是smallint ,在 C# 中是 a Short,而实体中的类型是int?

所以基本上发生的事情是这样的:

object s = (short?)1;
int? MyProperty  = (int?)s;

这会产生异常:

Method 'UserQuery+MyClass.MyProperty' not found.

   at System.RuntimeType.InvokeMember(String name, BindingFlags bindingFlags, Binder binder, Object target, Object[] providedArgs, ParameterModifier[] modifiers, CultureInfo culture, String[] namedParams)
   at System.Type.InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args)
   at UserQuery.Main() in C:\Users\royin\AppData\Local\Temp\LINQPad5\_oexzmkdz\query_deibtt.cs:line 33
   at LINQPad.ExecutionModel.ClrQueryRunner.Run()
   at LINQPad.ExecutionModel.Server.RunQuery(QueryRunner runner)
   at LINQPad.ExecutionModel.Server.StartQuery(QueryRunner runner)
   at LINQPad.ExecutionModel.Server.<>c__DisplayClass153_0.<ExecuteClrQuery>b__0()
   at LINQPad.ExecutionModel.Server.SingleThreadExecuter.Work()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()

我已经知道如何解决它:

这是通过改变:

typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { s });

typeof(MyClass).InvokeMember("MyProperty", BindingFlags.SetProperty, null, newObjectToReturn, new Object[] { (int?)(short?)s });

// btw , this also works : `(int?)(dynamic)s`

问题:

我怎样才能cast s获得实体的属性类型?

(int?)(short?)s

我已经知道如何从属性中获取类型:

newObjectToReturn.GetType().GetProperties().Where(otr =>otr.Name== "MyProperty").First().PropertyType

但我怎样才能将 s 投射到这个 ^ ?

标签: c#reflectioncastingtype-conversion

解决方案


推荐阅读