代码之家  ›  专栏  ›  技术社区  ›  BCS

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

  •  24
  • BCS  · 技术社区  · 15 年前

    我有这个密码:

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

    事实上,我得到:

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

    删除评论,我得到:

    修饰符“abstract”对此项无效

    如何使显式实现抽象化

    5 回复  |  直到 6 年前
        1
  •  33
  •   Jon Skeet    15 年前

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

    我会这样做:

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

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

        2
  •  16
  •   Stephen Swensen    13 年前

    虽然显式接口成员可能不是抽象的(或虚拟的),但它可以用抽象的(或虚拟的)成员来实现。 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分部视图中发现了这种需求,它不支持通用类型定义模型(据我所知)。

        3
  •  1
  •   Yekke    7 年前

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

    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
            }
        }
    }
    
        4
  •  0
  •   Olivier Jacot-Descombes    9 年前

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

    接口:

    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 它可以打电话。

        5
  •  0
  •   Guillermo Gutiérrez    6 年前

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

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

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

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