C#中的抽象显式接口实现

时间:2009-04-27 20:17:41

标签: c# interface abstract-class

我有这个C#代码:

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

    //abstract IEnumerator IEnumerable.GetEnumerator();
}

原样,我得到:

  

'Type'没有实现接口成员'System.Collections.IEnumerable.GetEnumerator()'。

删除评论,我得到:

  

修饰符'abstract'对此项无效

如何制作一个明确的实现摘要

5 个答案:

答案 0 :(得分:33)

有趣 - 我不确定你能不能。但是,如果这是您的真实代码,您是否希望以任何方式其他实现非通用GetEnumerator(),而不是通过调用通用代码?

我会这样做:

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

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

这使您免于必须在每个派生类中实现它的繁琐 - 这无疑都会使用相同的实现。

答案 1 :(得分:16)

虽然显式接口成员可能不是抽象(或虚拟),但它可以用抽象(或虚拟)成员1来实现:

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

我发现在强类型的ASP.NET MVC 3局部视图中需要这个,它不支持泛型类型定义模型(据我所知)。

答案 2 :(得分:1)

你实际上可以通过强制一个派生自抽象类的类来实现它,并且仍然允许它选择如何实现该接口 - 隐式或显式:

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

答案 3 :(得分:0)

我有一个稍微复杂的情况,我希望一个基类显式实现非泛型接口,派生类实现泛型接口。

接口:

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

public interface IIdentifiable
{
    object Id { get; }
}

我通过在基类中声明一个抽象的getter方法并让显式实现调用它来解决它:

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

请注意,基类没有可以调用的Id类型版本。

答案 4 :(得分:0)

似乎不可能进行抽象的显式接口实现,但是您可以采取一种变通方法来消除该错误,但仍要强制使用隐式接口来使用显式接口实现:

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

但是,正如对上述问题的评论所指出的那样:

  

如果选择让成员为非抽象成员,则编译器将允许子类使用(自己的)实现...