cal*_*rgs 23 .net c# oop generics
这是课堂设计问题.
我有主要的抽象类
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestriction<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestriction<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestriction<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
BlockRule rule=new BlockRule();
TimeRestriction t=new TimeRestriction();
AgeRestriction a=new AgeRestriction();
rule.Restrictions.Add(t);
rule.Restrictions.Add(a);
Run Code Online (Sandbox Code Playgroud)
我必须使用非泛型接口IR限制,以避免在主抽象类中指定泛型类型T. 我对仿制药很新.有人可以让我知道如何更好地设计这个东西吗?
Jac*_*ack 23
您的方法很典型(例如,IEnumerable <T>像这样实现IEnumerable).如果要为代码的使用者提供最大效用,那么在非泛型接口上提供非泛型访问器,然后将其隐藏在通用实现中会很好.例如:
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions { get; set; }
}
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T:struct
{
// hide IRestriction.Limit
new T Limit {get;}
}
public abstract class RestrictionBase<T> : IRestriction<T>
where T:struct
{
// explicit implementation
object IRestriction.Limit
{
get { return Limit; }
}
// override when required
public virtual T Limit { get; set; }
}
public class TimeRestriction : RestrictionBase<TimeSpan>
{
}
public class AgeRestriction : RestrictionBase<TimeSpan>
{
}
public class BlockRule : AbstractBlockRule
{
public override List<IRestriction> Restrictions { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我还在这里展示了使用基本限制类,但这不是必需的.
运行时将IRestriction<TimeSpan>和IRestriction<int>视为不同的不同类(它们甚至具有自己的一组静态变量)。在您的情况下,IRestriction<TimeSpan>和IRestriction<int>继承层次结构中唯一通用的类是IRestriction和object。
因此,确实,列出清单IRestriction是唯一明智的方法。
附带说明:Limit无论您使用的是IRestriction<TimeSpan>还是,都可以在其中拥有一个属性IRestriction<int>。我会做什么在这种情况下是定义另一个属性object Limit { get; }上IRestriction,并把它藏在实际执行。像这样:
public interface IRestriction
{
object Limit { get; }
}
public interface IRestriction<T> : IRestriction
where T : struct
{
new T Limit { get; set; }
}
public class TimeRestriction : IRestriction<TimeSpan>
{
public TimeSpan Limit { get; set; }
// Explicit interface member:
// This is hidden from IntelliSense
// unless you cast to IRestriction.
object IRestriction.Limit
{
get
{
// Note: boxing happens here.
return (object)Limit;
}
}
}
Run Code Online (Sandbox Code Playgroud)
这样,当您不在乎它是什么类型时,就可以Limit像访问object所有内容一样访问IRestriction。例如:
foreach(IRestriction restriction in this.Restrictions)
{
Console.WriteLine(restriction.Limit);
}
Run Code Online (Sandbox Code Playgroud)