2011-09-28 24 views
38

Tengo un método genérico cuyo comportamiento depende de T es el tipo de referencia o el tipo de valor. Se ve tan:¿Cómo determinar si T es un tipo de valor o una clase de referencia en genérico?

T SomeGenericMethod <T> (T obj) 
{ 
    if (T is class) //What condition I must write in the brackets? 
    //to do one stuff 
    else //if T is a value type like struct, int, enum and etc. 
    //to do another stuff 
} 

que no puede duplicar este método como:

T SomeGenericMethod <T> (T obj) where T : class 
{ 
//Do one stuff 
} 

T SomeGenericMethod <T> (T obj) where T : struct 
{ 
//Do another stuff 
} 

debido a que sus firmas son iguales. ¿Alguien puede ayudarme?

Respuesta

62

Puede utilizar el typeof operator con tipos genéricos, por lo typeof(T) obtendrá la referencia Type correspondiente a T, y luego usar el IsValueType propiedad:

if (typeof(T).IsValueType) 

O si desea incluir los tipos de valores con valores nulos como si nos re referencia tipos:

// Only true if T is a reference type or nullable value type 
if (default(T) == null) 
+1

Gracias por su explicación adicional sobre los tipos de valor que aceptan valores. – mkus

+0

La segunda opción es una posible comparación de un tipo de valor con nulo, que es algo que a ReSharper le gusta ladrar. ¿Hay alguna forma de evitar eso? – bubbleking

+0

@bubbleking: Depende de lo que estés tratando de lograr, realmente ... –

6

Type.IsValueType dice, naturalmente, si Type es un tipo de valor. Por lo tanto, typeof(T).IsValueType.

6

[la siguiente respuesta no comprueba el tipo estático de T pero el tipo de obj dinámico. Esto no es exactamente es lo que pidieron, pero ya que podría ser útil para su problema de todos modos, voy a seguir esta respuesta como referencia.]

Todos los tipos de valor (y sólo aquellos que se derivan de System.ValueType). Por lo tanto, la siguiente condición se puede utilizar:

if (obj is ValueType) { 
    ... 
} else { 
    ... 
} 
+0

T es un tipo, no una expresión, por lo que no puede utilizar 'is'. Además, considere dónde 'T' es exactamente System.ValueType, que es un tipo de referencia ... –

+0

@JonSkeet: Gracias, buen punto, cambiado a' obj es ValueType'. Dado que 'ValueType' es una clase abstracta,' obj' no puede ser exactamente 'ValueType' (por supuesto, esto supone que' obj' no es nulo ... Lo agregaré a mi respuesta). – Heinzi

+0

Eso no te dice acerca de 'T'. Considere 'SomeGenericMethod (null)' - 'int?' Es un tipo de valor, pero su condición no coincidirá. –

4

intente esto:

if (typeof(T).IsValueType) 
Cuestiones relacionadas