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

abstract explicit interface implementation in C#

我有这个密码:

1
2
3
4
5
6
abstract class MyList : IEnumerable<T>
{
    public abstract IEnumerator<T> GetEnumerator();

    //abstract IEnumerator IEnumerable.GetEnumerator();
}

现在,我得到:

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

删除评论,我得到:

The modifier 'abstract' is not valid for this item

如何使显式实现抽象化


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

我会这样做:

1
2
3
4
5
6
7
8
9
abstract class MyList<T> : IEnumerable<T>
{
    public abstract IEnumerator<T> GetEnumerator();

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

这就避免了在每个派生类中实现它的繁琐工作——毫无疑问,所有派生类都使用相同的实现。


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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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分部视图中发现了这种需求,它不支持通用类型定义模型(据我所知)。


实际上,您可以通过强制从抽象类派生的类来实现接口,并允许它选择如何隐式或显式实现该接口:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
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
2
3
4
5
6
abstract class MyList : IEnumerable<T>
{
    public virtual IEnumerator<T> GetEnumerator() {
        (this as IEnumerable).GetEnumerator();
    }
}

然而,正如对上述问题的评论所指出的:

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


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

接口:

1
2
3
4
5
6
7
8
9
public interface IIdentifiable<TKey> : IIdentifiable
{
    TKey Id { get; }
}

public interface IIdentifiable
{
    object Id { get; }
}

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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的类型化版本。