繁体   English   中英

继承非泛型一 C# 的泛型接口

[英]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>类是IRestrictionobject

因此,确实,拥有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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM