6

Estoy experimentando con métodos de extensión fluidos.Uso de restricciones genéricas con tipos de valor

Tengo el siguiente método de extensión simple para realizar un lanzamiento seguro.

 public static T As<T>(this Object source) 
     where T : class 
    { 
     return source as T; 
    } 

Esto funcionó bien, pero cuando traté de hacer que sea intuitivo de usar valuetypes con una sobrecarga

 public static T As<T>(this ValueType source) 
     where T : struct 
    { 
     return (T)source; 
    } 

me encontré con problemas. La lógica de resolución de métodos siempre elige el primer método anterior y proporciona un error de sintaxis (con precisión) de que la estructura no es una clase.

¿Hay alguna manera de manejar lo anterior, o debo ir por la ruta de eliminar la restricción mientras pruebo y manejo todos los tipos en el mismo método?

Editar ====: para responder a preguntas ====

Estoy compilando esto contra el marco 3.5. Realmente no estoy tratando de lograr nada en particular; esto es solo un experimento con lo anterior. Mi interés fue despertado y armé un código.

No me preocupa particularmente que siga siendo un yeso "seguro". Así es como comenzó, y puede mantenerse a salvo con el valor predeterminado(), pero ese no es realmente el foco de la pregunta y el código para garantizar que la 'seguridad' simplemente se oscurezca.

En cuanto a la expresividad, no value.As<int>() no es más expresivo que (int)value; pero ¿por qué el usuario del método tiene que 'solo saber' que solo funciona con tipos de referencia? Mi intento de trabajarlo fue más sobre el comportamiento esperado del método que sobre la escritura expresiva.

El fragmento de código value.As<DateTime>(), da el error "El tipo 'System.DateTime' debe ser un tipo de referencia para usarlo como parámetro 'T' en el tipo genérico o método .... As (object)" . Del mensaje de error veo que se está resolviendo usar el método superior anterior, ya que es el que requiere el tipo de referencia.

+0

¿Qué versión de C# ¿Estas usando? En .NET 4, se elige la segunda sobrecarga. –

+1

¿Quiere decir código como 'object o = 42; var i = o.As (); 'que da el error de sintaxis? ¿O podrías mostrar el código exacto que lo da? – svick

+0

El comentario de @ svick me trae a la mente quizás algo que podría estar tratando de hacer con un resultado de base de datos, como un DataRow, por ejemplo. Si es así, ya existe un método de extensión para convertir el valor del objeto en la fila a un tipo apropiado. [.Field ] (http://msdn.microsoft.com/en-us/library/bb360891.aspx) –

Respuesta

3

En .NET 4, la segunda sobrecarga se elige en función de la muestra del código. (También a prueba contra .NET 3.5, mismo resultado.)

int myInt = 1; 
long myLong = myInt.As<long>(); // chooses ValueType version 

Sin embargo, esto sólo nos lleva a la escena de la próxima crisis. El (T)source; genera una excepción de conversión no válida. Usted podría moverse por que al escribir el método como

public static T As<T>(this ValueType source) 
    where T : struct 
{ 
    return (T)Convert.ChangeType(source, typeof(T)); 
} 

Sin embargo, me pregunto lo que estás buscando realmente a lograr, ya que no veo el beneficio inmediato. (Y para el caso, esto no es segura como la versión source as T objeto.) Por ejemplo, ¿cómo es

long myLong = myInt.As<long>(); 

Cualquier más expresiva o más fácil de usar que

long myLong = (long)myInt; 
+0

Dado que ValueType es, a pesar de su nombre, en realidad un tipo de clase, esta última formulación requerirá el argumento. Lamentablemente, realmente no creo que haya ninguna forma de hacer que .net permita la sobrecarga en función del valor-tipo de un parámetro genérico. – supercat

Cuestiones relacionadas