C# 强制转换为变量类型

C# 强制转换为变量类型,c#,dynamic,reflection,C#,Dynamic,Reflection,是否可以从动态或对象强制转换为变量类型?目标变量类型是一个泛型类,只有特定的数据类型不同 我正在寻找抽象的解决方案,但情况是这样的:我希望为不同的实体使用一个Linq2SQL命令-我可以获取EntityFramework上下文的GetProperty+GetValue,但随后必须将其强制转换为某些确切的类型,但这些类型来自DB表的变量输入名称 我所拥有的示例: Type NewType = typeof(System.Data.Objects.ObjectSet<>); NewT

是否可以从动态或对象强制转换为变量类型?目标变量类型是一个泛型类,只有特定的数据类型不同

我正在寻找抽象的解决方案,但情况是这样的:我希望为不同的实体使用一个Linq2SQL命令-我可以获取EntityFramework上下文的GetProperty+GetValue,但随后必须将其强制转换为某些确切的类型,但这些类型来自DB表的变量输入名称

我所拥有的示例:

 Type NewType = typeof(System.Data.Objects.ObjectSet<>);
 NewType.MakeGenericType(new Type[] {"...some type here that's variable accordint to user input - like Person, Address, Contact, ..."});            
 Object MyObject = Context.GetType().GetProperty("the same variable like above - Person, Address,...", BindingFlags.Public | BindingFlags.Instance).GetValue(Context, null); // this is EntityFramework Context
所以我可以这样做:

 (from x in CastedObject where x.ID == ID select x).FirstOrDefault();
对于那些熟悉PHP的人,我尝试这样做:

 (from x in Context.$tablename where x.ID == ID select x).FirstOrDefault();

既然
NewType
是一种运行时类型,您怎么可能有编译时类型的变量
NewType
?编译器必须知道所有变量的“声明”类型。所以你想要的是不可能的

您可以将
MyObject
转换为
dynamic
。然后像
foreach(CastedToDynamic中的varx)
这样的东西将被编译(但没有编译时类型检查)

但是,不能在
动态表达式上使用LINQ。您必须重写如下内容:

    dynamic found = null;
    foreach (var x in CastedToDynamic)
    {
      if (x.ID == ID)
      {
        found = x;
        break;
      }
    }

注意:要使用的
==
重载将在运行时决定。因此,即使
ID
是(装箱的)
System.Guid
=
也会(取消装箱)调用该结构中定义的
=
的重载。所以这是可行的。

类似的东西可能会得到你所看到的东西(在很大程度上依赖于反射)

List mylist=new List();
动态数据=新的ExpandooObject();
data.Foo=“Foo”;
data.ID=1;
添加(数据);
数据=新的ExpandooObject();
data.Foo=“foobar”;
data.ID=2;
添加(数据);
数据=新的ExpandooObject();
data.Foo=“foobar2”;
data.ID=2;
添加(数据);
数据=新的ExpandooObject();
data.Foo=“foobar2”;
data.ID=3;
添加(数据);
int IDIMENTERESTEDIN=2;
var dynamicselected=mylist.Select(d=>((IDictionary)d))。其中(d=>
{
对象id;
if(d.TryGetValue(“ID”,out ID))
{
返回(id为int)和(int)id==IDIMENTERESTEDIN;
}
返回false;
});
foreach(dynamicselected中的var v)
{
Console.WriteLine(v[“Foo”]);
}
Console.ReadLine();
虽然我可能会跳过ExpandoObject直接去查字典:

        Dictionary<string, object> data = new Dictionary<string, object>();
        data["Foo"] = "foo";
        data["ID"] = 1;
字典数据=新字典();
数据[“Foo”]=“Foo”;
数据[“ID”]=1;
然后生成一个通用扩展函数:

静态类扩展函数
{
静态T GetValueAs(此字典对象,字符串键)
{
返回(T)obj[键];
}
静态bool TryGetValueAs(此字典为d,字符串键为out T T值)
{
对象id;
if(d.TryGetValue(键,输出id))
{
if(id为T)
{
值=(T)id;
返回true;
}
}
值=默认值(T);
返回false;
}
静态IEnumerable GetValuesWithKey(此列表、字符串键、T值)
{
返回列表。其中(d=>
{
T-id;
if(d.TryGetValueAs(键,输出id))
{
返回id.Equals(值);
}
返回false;
});
}
}
受此启发:


即使在EF中声明了新类型,但仅由变量“动态选择”吗?这看起来是个好主意,我明天会尝试,谢谢you@JanMatousek(您的第一条评论)您不可能声明“非固定”类型的变量。最接近的是泛型类型。但是,当您从“用户输入”构造类型时,它不会有帮助。泛型类型仍然是编译时类型,例如使用
void MyMethod(T arg){…}
时,类型
T
是编译时绑定的。所以运气不好。这个解决方案有效!foreach(varx in(dynamic)CastedObject){…}谢谢你编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。
        List<dynamic> mylist = new List<dynamic>();
        dynamic data = new ExpandoObject();
        data.Foo = "foo";
        data.ID = 1;
        mylist.Add(data);

        data = new ExpandoObject();
        data.Foo = "foobar";
        data.ID = 2;
        mylist.Add(data);


        data = new ExpandoObject();
        data.Foo = "foobar2";
        data.ID = 2;
        mylist.Add(data);

        data = new ExpandoObject();
        data.Foo = "foobar2";
        data.ID = 3;
        mylist.Add(data);

        int idiminterestedin = 2;

        var dynamicselected = mylist.Select(d=>((IDictionary<string,object>)d)).Where(d=>
        {
            object id;
            if (d.TryGetValue("ID",out id))
            {
                return (id is int) && (int)id == idiminterestedin;
            }
            return false;
        });

        foreach (var v in dynamicselected)
        {
            Console.WriteLine(v["Foo"]);
        }

        Console.ReadLine();
        Dictionary<string, object> data = new Dictionary<string, object>();
        data["Foo"] = "foo";
        data["ID"] = 1;
static class ExptensionFunction
{
    static T GetValueAs<T>(this Dictionary<string, object> obj, string key)
    {
        return (T)obj[key];
    }

    static bool TryGetValueAs<T>(this Dictionary<string, object> d, string key, out T value)
    {
        object id;
        if (d.TryGetValue(key, out id))
        {
            if (id is T)
            {
                value = (T)id;
                return true;
            }
        }

        value = default(T);
        return false;
    }

    static IEnumerable<Dictionary<string, object>> GetValuesWithKey<T>(this List<Dictionary<string, object>> list, string key, T value)
    {
        return list.Where(d =>
        {
            T id;
            if (d.TryGetValueAs<T>(key, out id))
            {
                return id.Equals(value);
            }
            return false;
        });
    }
}