使用扩展类

时间:2016-04-18 10:24:46

标签: c# generics

我有一个通用界面,我想拥有 self 类型的属性,即

public interface IFoo<TBar> : where TBar : ISomething 
    {
        TBar Prop1 { get; set; }
        IFoo<TBar> Unset { get; }
    }

这很好,直到我继承并创建一个(非泛型)类:

public class FooDesired : IFoo<Bar>
    {
        public Bar Prop1 { get; set; }
        public static Foo Unset { get { return new Foo(); } }
    }

public class FooReality : IFoo<Bar>
    {
        public Bar Prop1 { get; set; }
        public static IFoo<Bar> Unset { get { return new Foo(); } }
        public IFoo<Bar> IFoo<Bar>.Unset { get { return new Foo(); } }
    }

我目前的实施有两个问题:

1。此实现不实际允许Unset为静态。我通过显式接口实现来解决这个问题,但我总是对&#34;欺骗&#34;系统。

2. 如果我调用Foo.Unset我总是要把它强制转换回Foo(除非我设置了一个隐式运算符,但这只是隐藏问题而不是解决它)。

编辑真实问题:如何在一组类中强制执行静态属性?

**编辑:** 对于那些热衷于用例的人来说,让我们假设一旦完全成熟,所有动物物种的体内都会有一定数量的骨骼。因此,我希望Animal在Cat,Dog和Human上强制执行静态NumBones属性。这并不涵盖原始类的静态属性&#39;输入,但评论与答案有很好的联系。

1 个答案:

答案 0 :(得分:0)

显然这是不可能的,因为静态成员不加入继承链并且属于类型themeselfes而不是实例。因此,静态成员也不能实现任何接口成员。这意味着你实际上有两个成员,一个来自界面,另一个来自静态成员。但是正如您已经提到的,您可以包装其中一个:

public class Foo : IFoo<Bar>
{
    public Bar Prop1 { get; set; }
    public static Foo Unset { get { return new Foo(); } }
    public IFoo<Bar> IFoo<Bar>.Unset { get { (IFoo<Bar>) return Foo.Unset } }
}

现在,在您的消费者代码中,您可以使用以下内容:

var foo1 = Foo.Unset;       // compiler can infer foo1 is of type Foo, you don´t need to cast
var foo2 = new Foo().Unset; // returns IFoo<Bar> which can be cast to Foo

由于后者返回IFoo<T>而不是Foo(至少对于编译器而言),您必须转换实例。

通常这应该不是问题,因为您的消费代码甚至不知道哪个类Unset实际返回,它只知道接口IFoo并使用它。其余的是你想要在你的cunsumer代码中避免的实现细节,不是吗?