33

I have this C# code:

abstract class MyList : IEnumerable<T>
{
    public abstract IEnumerator<T> GetEnumerator();

    //abstract IEnumerator IEnumerable.GetEnumerator();
}

As is, I get:

'Type' does not implement interface member 'System.Collections.IEnumerable.GetEnumerator()'.

remove the comment and I get:

The modifier 'abstract' is not valid for this item

How do I make an explicit implementation abstract

1
  • 2
    This is a shortcoming the the C# compiler IMHO. There are many use cases where you will have to add a dummy implementation "just because". Also, if you chose to have the member non abstract, the compiler will allow subclasses without implementation, exposing the risk of calling the dummy implementation. Commented Aug 22, 2013 at 11:58

5 Answers 5

38

Interesting - I'm not sure you can. However, if this is your real code, do you ever want to implement the non-generic GetEnumerator() in any way other than by calling the generic one?

I'd do this:

abstract class MyList<T> : IEnumerable<T>
{
    public abstract IEnumerator<T> GetEnumerator();

    IEnumerator IEnumerable.GetEnumerator() 
    {
        return GetEnumerator();
    }
}

That saves you from the tedium of having to implement it in every derived class - which would no doubt all use the same implementation.

Sign up to request clarification or add additional context in comments.

2 Comments

I have no reason the think it will get implement any other way... but you never know. +1
Re your comment - I may have misread it... edited to fix it, and found the code identical to yours - so have deleted ;-p
23

While an explicit interface member may not be abstract (or virtual), it may be implemented in terms of an abstract (or virtual) member1:

public abstract class Foo: IEnumerable {
    IEnumerator IEnumerable.GetEnumerator() { 
        return getEnumerator();    
    }

    protected abstract IEnumerator getEnumerator(); 
}

public class Foo<T>: Foo, IEnumerable<T> {
    private IEnumerable<T> ie;
    public Foo(IEnumerable<T> ie) {
        this.ie = ie;
    }

    public IEnumerator<T> GetEnumerator() {
        return ie.GetEnumerator();
    }

    protected override IEnumerator getEnumerator() {
        return GetEnumerator();
    }

    //explicit IEnumerable.GetEnumerator() is "inherited"
}

I've found the need for this in strongly typed ASP.NET MVC 3 partial views, which do not support generic type definition models (as far as I know).

2 Comments

I found myself having to use this solution as well. Thanks! (Jon Skeets answer makes sense in the provided example, but if there is no such simple relation this seems to be the sanest solution as far as I'm aware.)
Thanks for this. This way you can also implement a kind of internal interface methods. If the interface is internal and the abstract method is internal too.
1

You actually can do it, by forcing a class, which derives from an abstract class, to implement an interface, and still allow it to choose how to implement that interface - implicitly or explicitly:

namespace Test
{
    public interface IBase<T>
    {
        void Foo();
    }

    public abstract class BaseClass<T> 
        where T : IBase<T>  // Forcing T to derive from IBase<T>
    { }

    public class Sample : BaseClass<Sample>, IBase<Sample>
    {
        void IBase<Sample>.Foo() { }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Sample sample = new Sample();

            // Error CS1061  'Sample' does not contain a definition for 'Foo' 
            // and no extension method 'Foo' accepting a first argument of type 'Sample' 
            // could be found(are you missing a using directive or an assembly reference ?)
            sample.Foo();

            (sample as IBase<Sample>).Foo(); // No Error
        }
    }
}

1 Comment

This is a "Curiouser and curiouser" pattern. Now you can add: public class Sample2 : BaseClass<Sample>, IBase<Sample2> which doesn't really do what you expect it to do. It is basically stating Base<T> where T : Base<T> it can be any Base<T>. E.g. X : Base<X> and Y : Base<X>
0

I had a slightly more complicated case where I wanted a base class to implement the non generic interface explicitly and a derived class implement the generic interface.

Interfaces:

public interface IIdentifiable<TKey> : IIdentifiable
{
    TKey Id { get; }
}

public interface IIdentifiable
{
    object Id { get; }
}

I solved it by declaring an abstract getter method in the base class and letting the explicit implementation call it:

public abstract class ModelBase : IIdentifiable
{
    object IIdentifiable.Id
    {
        get { return GetId();  }
    }

    protected abstract object GetId();
}

public class Product : ModelBase, IIdentifiable<int>
{
    public int ProductID { get; set; }

    public int Id
    {
        get { return ProductID; }
    }

    protected override object GetId()
    {
        return Id;
    }
}

Note that the base class does not have the typed version of Id it could call.

Comments

0

It seems not possible to do an abstract explicit interface implementation, but you can do a workaround to get rid of the error, but still force to use the explicit interface implementation by the implicit one:

abstract class MyList : IEnumerable<T>
{
    public virtual IEnumerator<T> GetEnumerator() {
        (this as IEnumerable).GetEnumerator();
    }
}

However, as pointed out by a comment on the question above:

If you chose to have the member non abstract, the compiler will allow subclasses without (an own) implementation...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.