2012-06-10 57 views
3

我已經創建了一個泛型類,但我知道運行時的類型,而不是設計,所以我想知道如何在運行時設置類型。,如何在運行時設置類型?

例如,我有:

public class MyGenericClass<T> 
{ 
.... 
} 

然後我嘗試使用它。我在其他類中有一個方法,它使用這個泛型類。在這個類的構造函數中,我接收到我想要的類型作爲參數,所以我有一個type屬性,用於保存我需要的類型。所以我想這個:

MyGenericClass<_typeNeeded> myClass = new MyGenericClass<typeNeeded>(); 

但這不起作用。

如何在運行時在我創建的類中設置類型?

我正在使用C#4.0。

謝謝。 Daimroc。

編輯:我想要做的是以下。我有一個需要對數據庫進行查詢的類。這個查詢總是返回相同的信息,一個類,但是包含這個類的信息來自不同的表。這是因爲我需要確定要使用的查詢。要決定使用什麼查詢,我使用我收到的類型。

正是因爲這個原因,我不知道設計中的類型,而是在運行時。

我可以使用一個接口,它將實現的類,並使用正確的類實例化的接口,但這使得我有一個開關或一個如果在實例化的時刻,這就是我儘量避免,我想要更通用的東西。另外,如果我使用這個解決方案,在實例的時候可以創建一個泛型類,所以我只有一個類,它會更易於維護。

+3

這是不可能的,沒有廣泛的思考。 – Femaref

+0

你見過[此鏈接](http://geekswithblogs.net/marcel/archive/2007/03/24/109722.aspx)? –

+0

爲什麼不使用動態關鍵字? –

回答

3

你可以在c以另一種方式讓你的類繼續,向構造函數傳遞你想要使用的類型並利用dynamic關鍵字。

例如:

class MyGeneralClass 
{ 
    dynamic myVariable; 
    Type type; 

    public MyGeneralClass(Type type) 
    { 
     this.type = type; 
     myVariable = Activator.CreateInstance(type); 
     //And then if your type is of a class you can use its methods  
     //e.g. myVariable.MyMethod(); 
    } 

    //If your function return something of type you can also use dynamic 
    public dynamic Function() 
    { 
     return Activator.CreateInstance(type); 
    } 
} 
+1

它是有用的動態類型。謝謝。 –

4

看看MakeGenericType方法。您可以使用它創建一個Type實例(可用於創建該類型的實例),並使用在運行時確定的一般參數值。但請注意,每當處理該對象的通用特徵時,您都需要更多的反思;您不能在代碼中創建一個變量,其類型是具有變量類型參數的泛型類型。

1

我沒有對你的代碼足夠的信息,但也許你可以使用簡單的多態:

public interface IMyInterface 
{ 
... 
} 

public class MyGenericClass<T> : IMyInterface 
{ 
.... 
} 

IMyInterface myClass = new MyGenericClass<typeNeeded>(); 

你也可以與工廠設計模式混合這一點,所以,其他一些類負責實例您的類型基於一些運行時知識。

當然,這假設你MyGenericClass這麼想的有這樣的方法:

public T GetT(){...} 

,或者如果它確實存在的所有T'types之間的附加關係,使他們都有共同的超可以說巴塞特您可以更改

public T GetT(){...} 

到:

public BaseT GetT(){...} 
+2

'typeNeeded'是OP的問題中的一個變量,所以'new MyGenericClassy ()'不會編譯。 –

+0

好的,好點。無論如何,如果我們知道T不是任何類型,而是我們知道的幾種類型之一,並且我們需要簡單而快速的解決方案(沒有反射),那麼我們可以使用一些帶有switch語句的工廠來實現類型實例化並堅持這種解決方案。 – 0lukasz0

+0

是的。讓我們看看OP是否想走這條路,需要更多的信息。 –

2

如果你想想看,沒有理由有一個通用的,其類型在運行時確定。泛型提供了強類型,但只有在編譯時知道類型纔可能。這是泛型的最強大的好處之一,它提供了安全性,因爲您知道對象可以執行什麼操作。在運行時,如果你不知道你得到的是什麼類型,那就失敗了這個目的,你將不得不鑽研反射這個強大的(但有時是危險的)世界。例如,

List<DateTime> list = new List<DateTime>(); 
foreach (DateTime item in list) 
    item.Minute + ": " + item.Hour 

因爲我知道在編譯時的類型,我可以將其存儲在一個通用的容器中,我使用它的時候有型的安全性。我知道該物品有分鐘和小時屬性。


如果您想要根據對象的類型執行操作,那麼您可以使用GetType()方法。這是您進入運行時類型識別和處理的窗口。

Result PerformQuery(object unknownObject) 
{ 
    switch (object.GetType()) 
    { 
     case typeof(ThisType): Do This; break; 
     case typeof(ThatType): Do That; break; 
    } 
} 

如果你打算做一些與該對象,那麼你要麼知道在編譯時間,這意味着你可以使用接口的方法名稱,

IFood hamburger = new Hamburger(); 
hamburger.BeEaten(); 

如果您沒有或不想使用可以使用反射或動態的接口,在這種情況下,如果我知道我想調用什麼方法,我將使用動態。

Result PerformQuery(object unknownObject) 
{ 
    if (object.GetType() == typeof(Pizza)) 
    { 
     dynamic pizza = unknownObject; 
     pizza.BakeInOven() // since I checked and know it is type Pizza it is 'somewhat' safe to do this, unless Pizza class changes the name of BakeInOven method. 
    } 
} 

最後,如果你不知道你想在編譯時,你可以使用反射來調用方法。

string methodName = CalculateWhatMethodShouldBe(); 
    MethodInfo myMethod = unknownObject.GetType().GetMethods().First(m => m.Name == methodName);  
    MethodInfo.Invoke(unknownObject);