使用扩展类的静态属性扩展泛型接口

本文关键字:扩展 属性 泛型接口 静态 | 更新日期: 2024-09-25 21:39:30

我有一个通用接口,我希望它具有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是静态的。我已经通过显式接口实现解决了这个问题,但我总是对"欺骗"系统持谨慎态度。

2.如果我打电话给Foo。如果不设置,我总是必须将其转换回Foo(除非我设置了一个隐式运算符,但这只是隐藏问题,而不是解决问题)。

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

**编辑:**对于那些热衷于用例的人来说,让我们假设所有动物物种一旦完全成熟,体内都有一定数量的骨骼。因此,我希望Animal对Cat、Dog和Human强制执行静态NumBones属性。这不包括原始类类型的静态属性,但注释中有很好的链接可以找到答案。

使用扩展类的静态属性扩展泛型接口

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

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代码中避免的实现细节,不是吗?