0

I have a generic interface which I would like to have a property of type self i.e.

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

This is fine until I inherit this and create a (non-generic) class:

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(); } }
    }

I have two issues with the current implementation of this:

1. This implementation does not actual allow Unset to be static. I've worked my way around that with Explicit Interface Implementation but I'm always wary of "tricking" the system.

2. If I call Foo.Unset I always have to cast it back to Foo (unless I setup an implicit operator but that's just hiding the issue rather than solving it).

Edited Real Question: How can I enforce the existence of a static property in a set of classes?

**Edit: ** For those who are keen for a use case, let's assume all Animal species have a set number of bones in their bodies once fully mature. Therefore I would like Animal to enforce a static NumBones property on Cat, Dog and Human. This doesn't cover the static property being of the original class' type but the comments have good links to answers to that.

Seb Andraos
  • 357
  • 3
  • 15
  • 2
    Issue 1: this is simply not possible. A derived class must implement everything from the interface. A static property does not implement a property from the interface. Issue 2: You don't need to cast it when you just need to access the properties from the interface. – wimh Apr 18 '16 at 10:34
  • 1
    duplicate for issue 1: [c#: Inherited/interface static member?](http://stackoverflow.com/q/259026/33499). Possible duplicate for issue 2:[Cast Interface in generic method](http://stackoverflow.com/q/1796655/33499) – wimh Apr 18 '16 at 10:37
  • 1
    We can't answer your real question because you didn't tell us what you're trying to do. Interfaces don't cover static methods - how could they? You need an instance to get the type to get the correct virtual method implementation. How would `IFoo.Unset` know which `Unset` method to call? And why do you think this would be useful in any case? What's the problem you're trying to solve by adding a static method to an interface? – Luaan Apr 18 '16 at 11:01
  • Thanks for the responses, it clearly does make sense that a static property cannot be defined in an interface. I have revised the "real question" to be slightly more specific. – Seb Andraos Apr 19 '16 at 08:56

1 Answers1

0

Obviously this is not possible as static members do not join the inheritance-chain and belong to the types themeselfes instead of the instances. Thus a static member can also not implement any interface-member. That means you have actually two members, the one from the interface and your static one. However as you already mentioned you can wrap one of them:

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 } }
}

Now within your consumer-code you have something like this:

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

As the latter returns an IFoo<T> and not a Foo (at least for the compiler) you have to cast the instance.

Usually this shouldn´t be a problem as your consuming code should not even know which class Unset actually returns, it simply knows the interface IFoo and works with this. The rest is implementation-detail which you want to avoid in your cunsumer-code, don´t you?

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • HimBromBeere, this is a great answer. I have slightly revised the question to be more specific about my requirement and less about the means of implementation. Everything written remains valid but if you have a solution to the "edited real question" then that would be a bonus. Thanks – Seb Andraos Apr 19 '16 at 09:07
  • If you want to ensure a property is set on all derived classes (every animal needs a set of bones) make the property `abstract` within the abstract base-class `Animal`, instead of `static`. Thus all derived classes have too implement this property somehow. – MakePeaceGreatAgain Apr 19 '16 at 09:11
  • Thanks, I was starting to suspect the big flaw here was in the use of an interface. I'll switch over to an abstract class. – Seb Andraos Apr 19 '16 at 09:49
  • Actually it´s not a bad idea to stay with the interface and create an intermediate abstract class which implements that interface. So for consumer-code you can deal with the interface while internally you work with the abstract class. – MakePeaceGreatAgain Apr 19 '16 at 09:54
  • That makes a lot of sense, thanks for all your help. – Seb Andraos Apr 19 '16 at 11:22