10

I come across a lot of situations where I have declared a generic interface and later I needed a non-generic version of this interface, or at least non-generic version of some of the methods or properties on that interface. I would usually declare a new non-generic interface and have it inherit the generic interface. The problem I am running into in shows in the example below:

public abstract class FormatBase { } public interface IBook<F> where F : FormatBase { F GetFormat(); } public interface IBook { object GetFormat(); } public abstract class BookBase : IBook<FormatBase>, IBook { public abstract FormatBase GetFormat(); object IBook.GetFormat() { return GetFormat(); } } 

Since the only way to declare the IBook (non-generic) interface is explicitly, how do you guys go about making it abstract?

6
  • 1
    This doesn't fix your problem, but don't you think it might make sense to make it BookBase<T> : IBook<T>, IBook where T : FormatBase? Otherwise, in your simple example at least, there's little to no benefit having IBook<T> instead of just IBook. Commented Jul 13, 2012 at 15:09
  • You are right. I updates the code. But the issue with the non generic abstract still exists. Commented Jul 13, 2012 at 15:16
  • You will also get a "'IBook<F>.GetFormat()' hides inherited member 'IBook.GetFormat()'. Use the new keyword if hiding was intended." warning. This is probably due to a poor design decision somewhere but without more information it is hard to say what a better design would be. Commented Jul 13, 2012 at 15:16
  • Not related to your question, but maybe you want to make the generic interface covariant in F, saying public interface IBook<out F>? Commented Jul 13, 2012 at 15:21
  • I made one more change to remove "Use new keyword..." message. IBook<F> does not inherit from IBook anymore. Thanks guys Commented Jul 13, 2012 at 15:22

2 Answers 2

7

Just delegate:

public abstract class BookBase : IBook<FormatBase> { public abstract FormatBase GetFormat(); object IBook.GetFormat() { return GetFormat(); } } 

Or, if you still want to differentiate both methods, delegate to a new method:

public abstract class BookBase : IBook<FormatBase> { public abstract FormatBase GetFormat(); public abstract object IBook_GetFormat(); object IBook.GetFormat() { return IBook_GetFormat(); } } 

You also need new to dodge a "hiding inherited member" warning:

public interface IBook<F> : IBook where F : FormatBase { new F GetFormat(); } 

Also, it might make more sense to let concrete classes decide on the concrete FormatBase:

public abstract class BookBase<F> : IBook<F> where F : FormatBase { public abstract F GetFormat(); object IBook.GetFormat() { return GetFormat(); } } 
Sign up to request clarification or add additional context in comments.

5 Comments

@spender, I don't see a better way to do it, do you?
@spender: use new or change the name... Since the OP wants the same name, either he uses new or gets a warning.... I don't know about you, but I don't like being warned about intentional decisions I've made...
Compare this with .NET's own interface IEnumerable<T> which derives from IEnumerable. It also has this method signature conflict (signatures agree, return types do not). Do they have this warning when they compile mscorlib, or do they say new?
The warning if clear: "use the new keyword if hiding was intended". As hiding is intended, the usage of new is fine.
@JeppeStigNielsen: Since it was an intentional decision, I'd bet my horse (if I had one) they use new...
4

Why you can't write implementation of explicit interface, instead of declaring it abstract?

public abstract class BookBase : IBook<FormatBase>, IBook { public abstract FormatBase GetFormat(); object IBook.GetFormat() { return GetFormat(); } } 

4 Comments

@Jordão release the trigger :)
@spender this line forces inheritors of BookBase to write their implementations of GetFormat
@spender I propose to add GetFormat implementation. That's the idea :)
Aww crap. I'm having a bad day. Ignore me.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.