爲了獲得最佳的編譯時安全,工廠類本身是可以通用的。通過限制泛型定義中的類型,程序總是可以假設只添加(或創建)了正確的類型。
雖然指定構造函數中的類型可以加快創建新的亞型,該檢查只能在運行時完成,但有例外
的幫助下通過繼承飛機本身,工廠可以調整到特定亞型。 例如具有以下設置:
public abstract class Airplane{}
public abstract class Fighter:Airplane{}
public class F15 : Fighter{}
public class F16 : Fighter{}
public class Boeing747 : Airplane{}
public class AirplaneFactory<T> where T : Airplane
{
List<T> list = new List<T>();
public void Add(T plane) => list.Add(plane); //"Add" used as a general example, but something like "Create" can be used as well. If T itself should be creatable directly, the constraint 'where T: Airplane, new()' can be used
}
下可以使用,最後一行給出一個編譯器錯誤:
var generalFact=new AirplaneFactory<Airplane>();
generalFact.Add(new F15()); //valid
generalFact.Add(new Boeing747()); //valid
var fighterFact = new AirplaneFactory<Fighter>();
fighterFact.Add(new F15()); //valid
fighterFact.Add(new Boeing747()); //Invalid!
因爲你可能需要更多的子類,然後繼承允許,您可以使用接口。
例如
public interface IAirplane{}
public interface IFighter:IAirplane{}
public interface IVertical:IAirplane{}
public abstract class Airplane:IAirplane{}
public class F15 : Airplane, IFighter{}
public class F16 : Airplane, IFighter{}
public class Boeing747 : Airplane{}
public class F14: Airplane,IFighter,IVertical{}
public class AirplaneFactory<T> where T : IAirplane
{
List<T> list = new List<T>();
public void Add(T plane) => list.Add(plane);
}
並與接口使用工廠:
var generalFact=new AirplaneFactory<IAirplane>();
generalFact.Add(new F15()); //valid
generalFact.Add(new Boeing747()); //valid
var fighterFact = new AirplaneFactory<IFighter>();
fighterFact.Add(new F15()); //valid
var verticalFact=new AirplaneFactory<IVertical>();
verticalFact.Add(new F14()); //valid
verticalFact.Add(new F15()); //Invalid
當然,因爲它是一個工廠,創建函數所預期的,而不是「添加」功能。但是對於一個通用的工廠,總是需要額外的規格。
public class AirplaneFactory<T> where T : IAirplane
{
List<T> list = new List<T>();
public void Add(T plane) => list.Add(plane);
public PlaneType Create<PlaneType>()
where PlaneType:class,T,new()
{
var res = new PlaneType();
Add(res);
return res;
}
}
例如
verticalFact.Create<F14>(); //valid
verticalFact.Create<F15>(); //Invalid!
見https://stackoverflow.com/questions/2742276/how-do-i-check-if:但是,這與重用工廠約束的方法來實現-a型是-A-亞型或最類型的-一個對象。我認爲這應該有你需要的信息。 – GBreen12
儘管可能不是......我想這不會在技術上「限制」這些類型,它只是讓你檢查傳入的類型。 – GBreen12
同樣的問題在這裏被問到https://stackoverflow.com/questions/8223073/define-list-of-specific-type-not-object,但是這個問題還沒有完全解答。 – 0liveradam8