我有一个通用界面,我想拥有 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;输入,但评论与答案有很好的联系。
答案 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代码中避免的实现细节,不是吗?