2010-03-14 65 views
5

在.NET框架中,有一个通用的接口IEnumerable<T>其中来自未通用IEnumerable继承,并且它们都具有一个GetEnumerator()方法。这两个GetEnumerator()之间唯一的区别是返回类型。 现在我有一个类似的设计,但是当我编译代码,编译器说:IEnumerable.GetEnumerator()和IEnumerable <T> .GetEnumerator()

MyInterface<T>.GetItem()“隐藏继承成员” MyInterface.GetItem()”。如果需要隐藏,请使用新关键字。

MyInterface<T>.GetItem()返回一个具体类型T,而MyInterface.GetItem()返回类型System.Object。

所以我想如果BCL团队的人编译.net框架,他们会得到相同的警告。

我觉得有编译器警告不好,你怎么看?我该如何解决这个问题?我的意思是,当调用MyInterface<T>.GetItem()时,我不想只是System.Object类型的一个实例。

在此先感谢! :-)

补充: 我说的接口过问:IMyInterface的从 IMyInterface的继承,并且它们都具有的GetItem()方法(IMyInterface.GetItem()返回一个类型T,而IMyInterface的。 GetItem()返回类型System.Object)。问题是,如果我们的代码只有这两个接口,也就是没有派生的具体类,编译源代码后我们会遇到编译器警告。

回答

10

它们并不是因为它们将一个版本编译为显式接口方法实现。它看起来像这样:

public class SomeClassThatIsIEnumerable<T> : IEnumerable<T> 
{ 
    public IEnumerator<T> GetEnumerator() 
    { 
     // return enumerator. 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return ((IEnumerable<T>)this).GetEnumerator(); 
    } 
} 

这是什么类型的构造确实是使第一GetEnumerator方法成为默认的方法,而其他GetEnumerator方法是唯一可如果主叫方先蒙上SomeClassThatIsIEnumerable的类型的IEnumerator,所以它避免了这个问题。

编辑:基于上面的补充,你会想使用new关键字:

public interface IMyInterface 
{ 
    object GetObject(); 
} 

public interface IMyInterface<T> : IMyInterface 
{ 
    new T GetObject(); 
} 

// implementation: 

public class MyClass : IMyInterface<string> 
{ 
    public string GetObject() 
    { 
     return "howdy!"; 
    } 

    object IMyInterface.GetObject() 
    { 
     return GetObject(); 
    } 
} 
+0

嗨,我不是说这个,请在​​帖子中看到我的“补充”。谢谢:) – 2010-03-15 11:54:24

+0

+1,即使你不能为明确的接口实现指定访问级别 – erikkallen 2010-03-15 12:18:48

+0

@Dylan:根据编译器建议使用new关键字。看到我上面的编辑。 – 2010-03-15 12:18:53

3

区别在于IEnumerable<T>IEnumerable是接口。在一个具体的类型中,它实现了两个接口,其中至少有一个必须被明确地实现。

在具体类型继承中,您必须使用new关键字来指示您要覆盖基类型的方法。当应用新关键字时,该方法不会被继承。这意味着myTypeInstance.Method将调用在MyType上定义的方法,而((MyBaseType) myTypeInstance).Method将调用在基本类型上定义的方法。

public interface Interface1 { 
    object GetItem(); 
} 

public interface Interface2<T> : Interface1 { 
    T GetItem(); 
} 

public class MyBaseType : Interface1 { 
    public object GetItem() { 
     // implements Interface1.GetType() 
     return null; 
    } 
} 

public class MyType<T> : Interface1, Interface2<T> { 
    public new T GetItem() { 
     // Implements Interface2<T>.GetItem() 
     return default(T); 
    } 

    object Interface1.GetItem() { 
     // implements Interface1.GetItem() 
     return this.GetItem(); // calls GetItem on MyType 
    } 
} 

var myType = new MyType(); 
var myTypeResult = myType.GetItem(); // calls GetItem on MyType 
var myBaseTypeResult = new ((MyBaseType) myType).GetItem(); // calls GetItem on MyBaseType 
+0

嗨,我在塞纳里奥,从接口1的接口2 继承,那么你会得到编译器警告。 – 2010-03-15 11:55:30

+0

只要其中一个GetItem方法明确实现,即使用Interface.GetItem,应该没有区别。 – AxelEckenberger 2010-03-15 20:53:09

+0

嗨,会有一个编译器警告,除非我使用“新”关键字。请在帖子中查看我的补充内容。:) – 2010-03-16 05:57:22

相关问题