关于C#:使用扩展类的静态属性扩展通用接口

Extending a generic interface with a static property of the extended class

本问题已经有最佳答案,请猛点这里访问。

我有一个通用接口,我希望它具有self类型的属性,即

1
2
3
4
5
public interface IFoo<TBar> : where TBar : ISomething
    {
        TBar Prop1 { get; set; }
        IFoo<TBar> Unset { get; }
    }

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

1
2
3
4
5
6
7
8
9
10
11
12
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是静态的。我已经用显式接口实现来解决这个问题,但我总是警惕"欺骗"系统。

2。如果我调用foo.unset,我总是必须将其转换回foo(除非我设置了隐式运算符,但这只是隐藏问题而不是解决问题)。

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

**编辑:**对于那些热衷于使用案例的人,让我们假设所有的动物物种在完全成熟后体内都有一定数量的骨骼。因此,我希望动物能够对猫、狗和人类强制执行静态麻木属性。这不包括原始类类型的静态属性,但是注释有很好的链接来回答这个问题。


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

1
2
3
4
5
6
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 } }
}

现在,在您的消费者代码中,您有如下内容:

1
2
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,而不是Foo(至少对于编译器而言),因此必须强制转换实例。

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