2013-03-21 107 views
0

是否可以從動態或對象轉換爲變量類型?目標變量類型是一個泛型類,只有特定的數據類型有所不同。轉換爲變量類型

我正在尋找抽象的解決方案,但情況是這樣的:我想單個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(); 
+0

我編輯了自己的冠軍。請參閱:「[應該在其標題中包含」標籤「](http://meta.stackexchange.com/questions/19190/)」,其中的共識是「不,他們不應該」。 – 2013-03-21 18:14:21

回答

0

由於NewType是一個運行時類型,你怎麼能有一個編譯時類型的變量NewType?編譯器必須知道所有變量的「聲明」類型。所以你想要的是不可能的。

東西你可以做的是鑄MyObjectdynamic。然後像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和)調用該結構內定義的==的超載。所以這個工作。

+0

即使NewType在EF中聲明,但只能由變量「動態選擇」? – 2013-03-21 16:41:50

+0

這看起來像個好主意,明天我會試試,謝謝 – 2013-03-21 16:48:20

+0

@JanMatousek(你的第一個評論)你不可能聲明一個「非固定」類型的變量。最接近的是泛型類型。但是,當你從「用戶輸入」構造類型時,它將無濟於事。泛型類型仍然是編譯時類型,例如'void MyMethod (T arg){...}'類型'T'是編譯時綁定的。所以沒有運氣。 – 2013-03-21 16:52:12

0

像這樣的事情可能會在你正在尋找什麼(在很大程度上依賴於反射)

 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?

Add property to anonymous type after creation