abstract explicit interface implementation in C#
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
如果你对这篇文章有疑问,欢迎到本站 社区 发帖提问或使用手Q扫描下方二维码加群参与讨论,获取更多帮助。

评论(5)

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

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.

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

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

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.
发布评论
需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。