2015-12-21 76 views
5

如果T是struct,則我想通過執行一個實現來實現我的通用IQueue<T>接口,而如果T是類,則實現另一個實現。如果類型參數是結構體或類,則選擇泛型實現

interface IQueue<T> { ... } 

class StructQueue<T> : IQueue<T> where T : struct { ... } 

class RefQueue<T> : IQueue<T> where T : class { ... } 

的,我想有一種基於T的一種工廠方法返回一個或一個實例另:

static IQueue<T> CreateQueue<T>() { 
    if (typeof(T).IsValueType) { 
     return new StructQueue<T>(); 
    } 
    return new RefQueue<T>(); 
} 

當然,編譯器表明T應當是非分別爲可空/可空類型參數。

有沒有辦法將T轉換爲struct類型(以及類類型)以使該方法編譯?這種運行時調度甚至可以用C#進行嗎?

+0

您可以使用Reflection –

+1

請注意,可爲空的值類型不會傳遞,也不會傳遞'class',也不會傳遞'struct'約束。你應該有第三個這個案例的實施課。 – PetSerAl

回答

5

您可以使用Reflection做這樣的:

static IQueue<T> CreateQueue<T>() 
{ 
    if (typeof(T).IsValueType) 
    { 
     return (IQueue<T>)Activator 
      .CreateInstance(typeof(StructQueue<>).MakeGenericType(typeof(T))); 
    } 

    return (IQueue<T>)Activator 
     .CreateInstance(typeof(RefQueue<>).MakeGenericType(typeof(T))); 
} 

該代碼使用Activator.CreateInstance method在運行時創建隊列。這個方法需要你想創建的對象的類型。

要創建Type表示通用類,此代碼使用MakeGenericType method從打開通用類型,如StructQueue<>創建閉合通用Type對象。

1

Yacoub Massad的回答是正確的,但稍作修改,您不需要爲每次調用CreateQueue運行MakeGenericType。

下面的代碼運行MakeGenericType每種類型的一次,因爲一個單獨的靜態變量存在於每一個類型的QueueFactory<T>,即QueueFactory<int>.queueType將得到StructQueue<int>,而QueueFactory<string>.queueType會得到RefQueue<int>

public class QueueFactory<T> 
{ 
    static Type queueType = typeof(T).IsValueType ? 
     typeof(StructQueue<>).MakeGenericType(typeof(T)) : typeof(RefQueue<>).MakeGenericType(typeof(T)); 

    public static IQueue<T> CreateQueue() 
    { 
     return (IQueue<T>)Activator.CreateInstance(queueType); 
    } 
} 

在我半的科學試驗,它在大約十分之一的時間創建了100萬個實例。

+0

謝謝,我對性能也有點擔心。 – akarnokd