[英]C#: generic method constraint on subclassed types
我有兩種基類:
public class Parent { }
public abstract class Child : Parent
{
string ChildKey { get; set; }
}
來自父母,有很多孩子:
public class Kid1 : Parent { public string Name { get; set; } }
public class Kid2 : Parent { public long Number { get; set; } }
...
還有許多兒童是特殊的兒童群體,具有額外的屬性:
public class Child1 : Child { public string Street { get; set; } }
public class Child2 : Child { public long Account { get; set; }}
現在,我有兩個通用的存儲庫類,其中的“特殊的”通過使用附加的過濾器在附加屬性上表現得更加具體:
public class Repository<T> : IRepository<T> where T : Parent
{
public IEnumerable<T> GetAll() { return something; }
}
public class ChildRepository<T> : Repository<T>, IChildrenRepository<T> where T : Child
{
public override IEnumerable<T> GetAll() { return base.GetAll().Where(x => x.ChildKey == "y"); }
}
與接口:
public interface IRepository<T> where T : Parent
{ IEnumerable<T> GetAll(); }
public interface IChildRepository<T> : IRepository<T> where T : Child { }
我還需要GetAll()結果的類型安全。
現在,我需要一個通用方法來創建所需的存儲庫:
IRepository<T> GetRepository() where T : WhatConstraint
{
if (typeof(Child).IsAssignableFrom(T))
return new ChildRepository<T>(); // return 1
return new Repository<T>(); // return 2
}
正確的約束是什么? return 1需要Child-Constraint(對於Return 2是錯誤的),它表示類型T不能用作方法中的類型參數,因為沒有從T到Child的隱式引用轉換。
T:Child-constraint在ChildRepository中更為精確(因此很有用,因為我可以依賴某些屬性)。 如果我使用相同的T:存儲庫的父約束,則必須一直檢查T是否始終從Child派生...
有什么解決辦法嗎?
好的,這是一個詳細的解決方案(可以寫得更短也更不易讀)。 由於存儲庫和ChildRepository具有沖突的約束(這對存儲庫有利,但對GetRepository-factory不利),因此無法使用new-keyword創建ChildRepository。 我必須通過CreateInstance創建此對象。
IRepository<T> GetRepository() where T : Parent
{
if (typeof(Child).IsAssignableFrom(T))
{
Type childType = typeof(T); // which is both, Parent and Child
Type classType = typeof(ChildRepository<>);
Type[] typeParams = { childType };
Type repositoryType = classType.MakeGenericType(typeParams);
return Activator.CreateInstance(resultType) as IRepository<T>;
}
return new Repository<T>();
}
該解決方案的缺點:更復雜的代碼分析,不清楚的結果可為空性,不是真正直觀的可讀性(尤其是現有的約束)。 但這有效。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.