2010-03-14 20 views
5

En el marco NET, hay un IEnumerable<T> interfaz genérica que hereda de la no-genérico IEnumerable, y ambos tienen un método GetEnumerator(). Los únicos diferentes entre estos dos GetEnumerator() es el tipo de devolución. Ahora tienen un diseño similar, pero cuando compilar el código, el compilador dijo: 'miembro de cueros heredada'IEnumerable.GetEnumerator() y IEnumerable <T> .GetEnumerator()

MyInterface<T>.GetItem()MyInterface.GetItem()'. Usa la nueva palabra clave si te intentabas esconder.

MyInterface<T>.GetItem() devuelve un tipo concreto T, mientras que MyInterface.GetItem() devuelve tipo System.Object.

Así que creo que si los chicos del equipo BCL compilan el .NET Framework, recibirán la misma advertencia.

Creo que tener advertencias de compilador no es bueno, ¿qué opinas? ¿Y cómo puedo resolver este problema? Quiero decir que quiero obtener el tipo concreto T cuando llamo al MyInterface<T>.GetItem() no solo una instancia de tipo System.Object.

¡Gracias de antemano! :-)

Suplemento: que digo las interfaces de theirselves: IMyInterface hereda de IMyInterface, y ambos tienen el método GetItem() (el IMyInterface.GetItem() devuelve tipo T, mientras que IMyInterface. GetItem() devuelve tipo System.Object). El problema es que, si nuestro código solo tiene estas dos interfaces, es decir, no hay clases concretas derivadas, nos encontraremos con la advertencia del compilador después de compilar el código fuente.

Respuesta

10

No lo hacen porque compilan una versión como Implementación explícita del método de interfaz. Se ve así:

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

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

Lo que este tipo de construcción no es hacer el primer método GetEnumerator convertirse en el método por defecto, mientras que el otro método GetEnumerator sólo es accesible si la persona que llama primero arroja SomeClassThatIsIEnumerable al tipo IEnumerator, por lo que evita el problema

Editar: basado en el suplemento anterior, se querría usar la nueva palabra clave:

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

Hola, no estoy diciendo esto, por favor vea mi "Suplemento" en la publicación. Gracias :) –

+0

+1 aunque no se puede especificar el nivel de acceso para una implementación de interfaz explícita – erikkallen

+0

@Dylan: utilice la nueva palabra clave como recomienda el compilador. Ver mis ediciones arriba. –

3

La diferencia es que IEnumerable<T> y IEnumerable son interfaces. En un tipo concreto, que implementa ambas interfaces, al menos una de ellas debe implementarse explícitamente.

En una herencia de tipo concreto, debe usar la nueva palabra clave para indicar que desea sobrescribir el método del tipo base. Al aplicar la nueva palabra clave, el método no se hereda. Esto significa que myTypeInstance.Method llamará al método definido en MyType, mientras que ((MyBaseType) myTypeInstance).Method llamará al método definido en el tipo de base.

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

Hola, en mi senario, los Interfaz2 hereda de Interface1, por lo que recibirá la advertencia del compilador. –

+0

No debería haber ninguna diferencia, siempre que uno de los métodos de GetItem se implemente explícitamente, es decir, utilizando Interface.GetItem. – AxelEckenberger

+0

Hola, habrá una advertencia del compilador, a menos que use la palabra clave "nueva". Por favor vea mi suplemento en la publicación.:) –

Cuestiones relacionadas