2009-12-03 9 views
9

Aquí hay un código C# que no se compila, dando el siguiente mensaje:no se puede convertir de 'cabo T' a 'Salida de componente'

no se puede convertir de 'cabo T' a 'Salida de componente'

public void Get<T>(out T c) where T : Component 
    { 
     m_components.TryGetValue(typeof(T), out c); 
    } 

Aquí es código que hace compilar:

public void Get<T>(out T c) where T : Component 
    { 
     Component temp; 
     m_components.TryGetValue(typeof(T), out temp); 
     c = (T)temp; 
    } 

me pregunto por qué el primer código no es válido desde el "donde T: Componente" establece explícitamente que T es del tipo Componente.

Gracias

+0

¿Por qué necesitarías hacer "Obtener " un método genérico si T se define como del tipo Componente? Puede ser que usted no lo haya mencionado; t mencionó el escenario exacto aquí. –

+3

* twiddles pulgares esperando que el Sr. Skeet nos aclare sobre este tema intrigante * – tster

+0

Esto es un duplicado. http://stackoverflow.com/questions/1207144/c-why-doesnt-ref-and-out-support-polymorphism/1207302#1207302 –

Respuesta

4

Voy a intentar una versión más elaborada de la respuesta de @ Rex y una versión ligeramente corregida de la firma de @ Courtney en que el tipo es Componente, no objeto. La respuesta de Courtney es básicamente correcta, solo que los tipos están un poco mal.

bool TryGetValue(Type key, out Component result) 
{ 
     if (this.Contains(key)) 
     { 
      result = this[key]; // the type of result is Component! 
      return true; 
     } 

     return false; 
} 

pasando T como el tipo de objeto, que están tratando de forma implícita echados del componente Tipo de base a un subtipo de T. Esa es la razón por su segundo ejemplo funciona. TryGetValue no sabe acerca de su Tipo genérico T, cree que todo en m_Components es un objeto Componente.

Esto es una cosa bastante común quedarse estancado pensando hacia atrás. Debido a que es un parámetro, no el tipo de devolución, te absorbe la idea de que debería funcionar como cualquier otro parámetro. Sin embargo, debido a que es , en realidad se lo considera mejor como un tipo de devolución para este fin ... intentará asignar el valor de su trabajo interno al parámetro que proporcione.

3

creo que el problema está en el cabo y que no se refiere a los genéricos

podemos producir el mismo error de la siguiente manera

class A 
{ 
} 

void fn(out object x) 
{ 
x= new object(); 
} 
void main() 
{ 
A x; 
fn(out x); //error 
} 
-2

Esto es interesante.

no tengo una respuesta, pero no vale de nada (al menos para mí), que las siguientes obras:

public void M<T> (out T c) where T : Test 
    { 
     // Test m; 
     // A(out m); 
     // c = (T) m; 

     A(out c); 
    } 

    public void A<T> (out T t) where T : Test 
    { 
     t = null; 
    } 

- Editar:

(es interesante porque incluso si se trata de out object t todavía no es convertible entre out T y out object)

12

es porque out tipos de parámetros no pueden ser covariant/contravariant. El tipo de la variable debe coincidir exactamente con el tipo de parámetro.

Ver:

class Super { } 
class Sub : Super { } 

void Test(out Super s) 
{ 
    s = new Super(); 
} 

void Main() 
{ 
    Sub mySub = new Sub(); 
    Test(out mySub); //doesn't work 
} 
+0

me lo ganaste :( – FlySwat

+0

Buena explicación y ejemplo –

0

OK, he averiguado:

¿Qué pasa si usted tiene lo siguiente:

public class BaseClass { ... } 
public class SubClass : BaseClass { ... } 

entonces tengo el código:

Dictionary<int, BaseClass> comps; 

public void Get<T>(int num, out T c) where T : BaseClass 
{ 
    comps.TryGetValue(num, out c); 
} 

An d Trato de llamar como sigue:

SubClass sub; 
Get<SubClass>(1, out sub); 

Sub suponer que el BaseClass con una llave de 1 era en realidad un BaseClass y no un SubClass.O quizás es OtherSubClass donde OtherSubClass : BaseClass

-2

yo supongo que TryGetValue parece:

bool TryGetValue (Type someType, out Object result){ 
    // do stuff// 
} 

tanto result es un object en lugar de component y no se puede convertir implícitamente, que es lo que estamos tratando de hacer.

Cuestiones relacionadas