C# 继承非泛型C的泛型接口#
这是课堂设计问题 我有一个主要的抽象类C# 继承非泛型C的泛型接口#,c#,.net,oop,generics,C#,.net,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
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);
公共抽象类AbstractBlockRule
{
公共长Id{get;set;}
公共摘要列表限制{get;};
}
公共接口i限制{}
公共接口IRestriction:IRestriction,其中T:struct
{
T限制{get;}
}
公共时间限制:i限制
{
公共时间跨度限制{get;set;}
}
公共行政限制:直接限制
{
公共整数限制{get;set;}
}
公共类BlockRule:AbstractBlockRule
{
公共虚拟列表限制{get;set;}
}
BlockRule规则=新的BlockRule();
时间限制t=新的时间限制();
AgeRestriction a=新的AgeRestriction();
规则。限制。添加(t);
规则.限制.加入(a);
我必须使用非泛型接口IRestriction,以避免在主抽象类中指定泛型类型T。我对泛型很陌生。有人能告诉我如何更好地设计这个东西吗?您的方法是典型的(例如,IEnumerable实现了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; }
}
foreach(IRestriction restriction in this.Restrictions)
{
Console.WriteLine(restriction.Limit);
}
公共抽象类AbstractBlockRule
{
公共长Id{get;set;}
公共抽象列表限制{get;set;}
}
公共接口限制
{
对象限制{get;}
}
公共接口IRestriction:IRestriction
其中T:struct
{
//隐藏限制。限制
新的T限制{get;}
}
公共抽象类限制库:IRestriction
其中T:struct
{
//显式实现
对象限制。限制
{
获取{返回限制;}
}
//在需要时覆盖
公共虚拟T限制{get;set;}
}
公共类时间限制:RestrictionBase
{
}
公共类限制:限制基
{
}
公共类BlockRule:AbstractBlockRule
{
公共覆盖列表限制{get;set;}
}
这里我还演示了如何使用一个基本限制类,但它不是必需的。接口是需要由实现该协定的实体遵循的协定 您已经创建了两个同名的合同
i限制
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;}
}
就我所见,您基本上可能需要的是一个可以被限制的类的标志,它应该实现IRestriction
非泛型接口
第二个接口似乎是可限制的对象,也包含一个limit属性。
因此,第二个IRestriction
接口的定义可以是ILimitRestriction
或任何适合您业务需要的名称
因此,ILimitRestriction
可以从IRestriction
继承,这将标记继承ILimitRestriction
的类
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;}
}
公共抽象类AbstractBlockRule
{
公共长Id{get;set;}
公共摘要列表限制{get;};
}
公共接口i限制{}
公共接口IRestrictionWithLimit:IRestriction其中T:struct
{
T限制{get;}
}
公共时间限制:IRestrictionWithLimit
{
公共时间跨度限制{get;set;}
}
公共管理限制:有限制的直接限制
{
公共整数限制{get;set;}
}
公共类BlockRule:AbstractBlockRule
{
公共虚拟列表限制{get;set;}
}
运行时将IRestriction
和IRestriction
视为不同的类(它们甚至有自己的静态变量集)。在您的情况下,继承层次结构中的irestruction
和irestruction
共同的类只有irestruction
和object
因此,拥有一个i限制列表是唯一明智的选择
作为旁注:您在其中有一个属性Limit
,无论您是处理IRestriction
还是IRestriction
,您都可能希望访问该属性。在这种情况下,我将在IRestriction
上定义另一个属性对象限制{get;}
,并将其隐藏在实际实现中。像这样:
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;
}
}
}
对我来说,很难改进你的代码。如果需要,非泛型基接口可以有一个属性ValueType-BoxedLimit{get;}
,但我不确定它是否有用。毕竟,为什么您需要不同类型对象的列表
(当然,当您将通用接口与值类型(结构)一起使用时,使其协变的明显想法,IRestriction
,是没有用的,因为C#和.NET不支持值类型的协变。)我不知道为什么不将抽象类或方法设置为泛型。限制是最小值还是最大值?如果是这样的话,IComparable
可能会更有用。