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

发布于 2024-07-18 16:07:30 字数 430 浏览 8 评论 0原文

我有这个 C# 代码:

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

    //abstract IEnumerator IEnumerable.GetEnumerator();
}

按原样,我得到:

“Type”未实现接口成员“System.Collections.IEnumerable.GetEnumerator()”。

删除评论,我得到:

修饰符“abstract”对此项目无效

如何制作显式实现抽象

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

酸甜透明夹心 2024-07-25 16:07:30

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

我会这样做:

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

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

这可以让您免于必须在每个派生类中实现它的乏味 - 毫无疑问,所有派生类都会使用相同的实现。

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.

梦中楼上月下 2024-07-25 16:07:30

虽然显式接口成员可能不是抽象(或虚拟)的,但它可以根据抽象(或虚拟)成员来实现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 部分视图需要此功能,该视图不支持泛型类型定义模型(据我所知)。

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).

胡大本事 2024-07-25 16:07:30

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

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

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

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

接口:

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 的类型化版本。

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.

只是一片海 2024-07-25 16:07:30

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

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

但是,正如对该问题的评论所指出的那样多于:

如果您选择让成员非抽象,编译器将允许子类没有(自己的)实现...

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文