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
号
如何使显式实现抽象化
有趣-我不确定你能不能。但是,如果这是您真正的代码,您是否希望以任何方式实现非泛型
我会这样做:
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; } } |
。
注意,基类没有它可以调用的