[英]Generic Interface inheriting Non-Generic One C#
这是班级设计问题。
我有主要的抽象类
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);
我必须使用非泛型接口 IRestriction 来避免在主抽象类中指定泛型类型 T。 我对泛型很陌生。 有人可以让我知道如何更好地设计这个东西吗?
您的方法是典型的(例如, 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; }
}
我还在此处展示了使用基本限制类,但这不是必需的。
运行时将IRestriction<TimeSpan>
和IRestriction<int>
视为不同的不同类(它们甚至有自己的一组静态变量)。 在您的情况下,继承层次结构中IRestriction
IRestriction<TimeSpan>
和IRestriction<int>
唯一IRestriction<TimeSpan>
类是IRestriction
和object
。
因此,确实,拥有IRestriction
列表是唯一明智的方法。
附带说明:您在那里有一个属性Limit
,无论您是在处理IRestriction<TimeSpan>
还是IRestriction<int>
,您都可能想要访问它。 在这种情况下我会做的是定义另一个属性object Limit { get; }
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;
}
}
}
这样,当您不关心它是什么类型时,您可以在所有IRestriction
Limit
作为object
访问。 例如:
foreach(IRestriction restriction in this.Restrictions)
{
Console.WriteLine(restriction.Limit);
}
接口是实现合约的实体需要遵循的合约。
您已经创建了两个同名的合约IRestriction
据我所知,您基本上可能需要一个可以限制类的标志,它应该实现IRestriction
非通用接口。
第二个接口似乎是也包含限制属性的受限制对象。 因此,第二个IRestriction
接口的定义可以是ILimitRestriction
或任何适合您业务需求的名称。
因此ILimitRestriction
可以从IRestriction
继承,这将标记继承ILimitRestriction
类仍然是IRestriction
对象
public abstract class AbstractBlockRule
{
public long Id{get;set;}
public abstract List<IRestriction> Restrictions {get;};
}
public interface IRestriction{}
public interface IRestrictionWithLimit<T>:IRestriction where T:struct
{
T Limit {get;}
}
public TimeRestriction:IRestrictionWithLimit<TimeSpan>
{
public TimeSpan Limit{get;set;}
}
public AgeRestriction:IRestrictionWithLimit<int>
{
public int Limit{get;set;}
}
public class BlockRule:AbstractBlockRule
{
public virtual List<IRestriction> Restrictions {get;set;}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.