转换为变量类型
是否可以从动态或对象转换为变量类型?目标变量类型是一个泛型类,只有特定的数据类型有所不同。转换为变量类型
我正在寻找抽象的解决方案,但情况是这样的:我想单个Linq2SQL命令为不同的实体 - 我可以GetProperty + GetValue的EntityFramework上下文,但它必须被铸造成一些确切的类型,但这些来自变量输入 - 数据库表的名称。的我有什么
例子:
NewType CastedObject = (NewType) MyObject;
// or
NewType CastedObject = Convert.ChangeType(MyObject, NewType);
// or
NewType CastedObject = MyObject as NewType;
,所以我可以做到这一点:
(from x in CastedObject where x.ID == ID select x).FirstOrDefault();
的我需要什么,但不知道该怎么办呢
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
例
对于那些熟悉PHP的人,我试图这么做:
(from x in Context.$tablename where x.ID == ID select x).FirstOrDefault();
由于NewType
是一个运行时类型,你怎么能有一个编译时类型的变量NewType
?编译器必须知道所有变量的“声明”类型。所以你想要的是不可能的。
东西你可以做的是铸MyObject
到dynamic
。然后像foreach (var x in CastedToDynamic)
这样的东西会编译(但没有编译时类型检查)。
不过,您不能在dynamic
表达式上使用LINQ。你将不得不重新编写,如:
dynamic found = null;
foreach (var x in CastedToDynamic)
{
if (x.ID == ID)
{
found = x;
break;
}
}
注:哪超载的==
使用将在运行时决定。因此,即使ID
是(盒装的)System.Guid
,也就是说,==
将(unbox和)调用该结构内定义的==
的超载。所以这个工作。
即使NewType在EF中声明,但只能由变量“动态选择”? – 2013-03-21 16:41:50
这看起来像个好主意,明天我会试试,谢谢 – 2013-03-21 16:48:20
@JanMatousek(你的第一个评论)你不可能声明一个“非固定”类型的变量。最接近的是泛型类型。但是,当你从“用户输入”构造类型时,它将无济于事。泛型类型仍然是编译时类型,例如'void MyMethod
像这样的事情可能会在你正在寻找什么(在很大程度上依赖于反射)
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();
虽然我可能会跳过ExpandoObject和直行的字典:
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;
});
}
}
受此启发:
Creating an anonymous type dynamically?
和
我编辑了自己的冠军。请参阅:“[应该在其标题中包含”标签“](http://meta.stackexchange.com/questions/19190/)”,其中的共识是“不,他们不应该”。 – 2013-03-21 18:14:21