2013-01-31 79 views
2

我有一個工廠類,返回從抽象類型繼承的具體實例。這些具體實例的數據類型也具有通用屬性,因爲每個實例都需要不同的數據類型。 Data屬性也存在於抽象類型中,因爲它在工廠中設置。是否可以重寫抽象類的工廠方法中的泛型類型?

public static class FactoryClass 
{ 
    public static TType CreateNewClass<TType>(object data) 
     where TType : AbstractClass<object>, new() 
    { 
    var newClass = new TType {Data = data}; 
    // do some stuff 
    // keep track of all created types in a list 
    List.Add(newClass); 
    return newClass; 
    } 

    private List<AbstractClass<object>> MyList = new List<AbstractClass<object>>() 
} 

public abstract class AbstractClass<TData> 
{ 
    internal AbstractClass() 
    { 
    // do constructor things 
    } 

    protected SomeCommonFunction() 
    { 
    // common code for abstract base class 
    } 

    public abstract void DoSomethingToData(); 

    TData Data; 
} 

public class ExampleClass : AbstractClass<string[]> 
{ 
    public override void DoSomethingToData() 
    { 
    // sort the strings or something 
    // call the abstract code 
    } 
} 

當我嘗試並調用FactoryClass.CreateNewClass<ExampleClass>(myStringArray)我得到一個錯誤,它需要被強制轉換爲AbstractClass<object>

有沒有更好的辦法做我想要做什麼?

+1

你指的抽象類,AbstractBase和AbstractBaseClass。只是很多錯別字? – devio

+0

是的,哎呀。我從頭開始重新輸入,因爲它比清理我正在編寫的代碼更容易理解SO問題。修復。 – WarrenB

回答

3

嗯,這就是問題所在:

where TType : AbstractClass<object> 

這個約束是完全一個編譯器抱怨。

像你真正想要的東西,聽起來這好像是對我說:

public static TContainer CreateNewClass<TContainer, TData>(TData data) 
    where TContainer : AbstractClass<TData>, new() 

不幸的則需要你指定類型參數的方法 - 但至少它的類型方面是安全的你正在使用的數據。您可以通過創建兩個通用的方法和一個單獨的類來解決這兩者之間使用,讓你寫的東西,如:

FactoryClass.For(myStringArray).CreateNewClass<ExampleClass>(); 

For方法將返回一個泛型類型的類型參數string[],然後CreateNewClass將是一個實例方法,它將容器類型作爲數據類型。

但是,您的列表根本無法以其當前形式工作。您可能希望創建一個非通用基類AbstractClass

public abstract class AbstractClass 
{ 
    // Anything which doesn't use TData 
} 

則:

public abstract class AbstractClass<TData> : AbstractClass 

在這一點上你的工廠的名單將是一個List<AbstractClass>;你不會以編譯時安全的方式知道每個條目的數據類型......這是非常有意義的,因爲每個元素可以使用不同的類型。

(呵呵,當然你的列表字段將需要是靜態的,如果你想從一個靜態方法來訪問它...)