2010-05-27 12 views
6

Tengo varios objetos con plantilla que implementan todos la misma interfaz:C# determinación del tipo genérico

I.E.

MyObject<datatype1> obj1; 
MyObject<datatype2> obj2; 
MyObject<datatype3> obj3; 

Quiero guardar estos objetos en una lista ... creo que lo haría así:

private List<MyObject<object>> _myList; 

entonces yo quiero crear una función que toma el parámetro 1, al ser un tipo de datos , para ver si un objeto que usa ese tipo de datos existe en mi lista ... no tengo ni idea de cómo hacerlo. En Pseudo código sería:

public bool Exist(DataType T) 
{ 
    return (does _myList contain a MyObject<T>?); 
} 

algunas aclaraciones ....

Mi interfaz es IMyObject<T>, mis objetos son MyObject<T>. Tengo una nueva clase MyObjectManager que necesito tener una lista de MyObject<T> almacenada dentro. Necesito una función para verificar si existe un MyObject<T> en esa lista. Los tipos T son tipos de datos que se generaron automáticamente utilizando clases T4 ... POCO de mi Modelo de datos de entidad.

+0

lo que si contiene una 'MiObjeto 'y' U' hereda 'T'? – SLaks

+0

Bueno, mi U se genera automáticamente utilizando las clases T4 y EF POCO. –

+0

¿Las clases se heredan entre sí? – SLaks

Respuesta

6

se puede hacer una función genérica:

public bool Exists<T>() where T : class { 
    return _myList.OfType<MyObject<T>>().Any(); 
} 

Tenga en cuenta que esto requiere que usted sabe T en tiempo de compilación.

Si todo lo que tiene es un objeto System.Type en tiempo de ejecución, que necesita para utilizar la reflexión:

public bool Exists(Type t) { 
    var objectOfT = typeof(MyObject<>).MakeGenericType(t); 

    return _myList.Any(o => o.GetType() == objectOfT); 
} 

Tenga en cuenta, sin embargo, que un List<MyObject<object>> no puede sostener una MyObject<SomeType>.
Necesita cambiar la lista a List<object>, o hacer MyObject implementar o heredar un tipo no genérico y hacer que la lista contenga ese tipo.

+0

Mi clase que almacena la lista no tendrá un tipo genérico. Sin embargo, la T en MyObject se conoce en tiempo de compilación y el espacio de nombres para estos objetos se hace referencia en esta clase. Cuando pruebo tu primer ejemplo, dice que el tipo T debe ser un tipo de referencia para usarlo como parámetro. Quiero que T sea un tipo genérico, así que puedo pasar cualquier tipo de datos, ya sea int, cadena, etc. –

+0

Necesita agregar una contstraint 'where T: class', para que coincida con la restricción en' MyObject'. – SLaks

+0

Lo tengo ... tuve que agregar bool público Existe () donde T: clase ... ¡gracias! –

0

Dado que todos implementan la misma interfaz, en lugar de enviarlos a objetos y llamar a GetType (que puede ser costoso), ¿por qué no agregar una propiedad a su interfaz llamada nombre de clase (o algo)? Entonces puedes usar el linq para tomar esa propiedad. Y no se olvide de using System.Linq

using System.Linq; 

public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck) 
{ 
    return objects.Any(t => t.ObjectName == typeToCheck.ObjectName); 
} 
+0

Mi interfaz es IMyInterface

1

¿Qué tal un método de extensión?

public static bool HasAny(this IEnumerable source, Type type) { 
    foreach (object item in source) 
     if (item != null && item.GetType().Equals(type)) 
      return true; 

    return false; 
} 

Uso:

bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>)); 

Tenga en cuenta que si usted no quiere tener que escribir typeof(...) - es decir, si usted quiere que su básicamente Exist método para única cuidado acerca de los objetos de tipo MyObject<T>, me gustaría ir con algo así como la respuesta de SLaks:

public static bool Exist<T>(this IEnumerable source) { 
    return source.OfType<MyObject<T>>().Any(); 
} 

Además, SLaks es justo que usted r eally no puede tener un List<MyObject<object>> que está lleno de cualquier cosa que no sean objetos del tipo MyObject<object> o alguna clase derivada (y MyObject<datatype1>, etc.do no derivado de MyObject<object> - los genéricos no funcionan de esa manera).

Otra forma en que podría sugerir trabajar con el conjunto "no se puede obtener el tipo de una clase genérica utilizando un problema System.Type sin usar reflexión" sería esta: Haga que su MyObject<T> implemente una interfaz no genérica, como esto:

public interface IMyObject { 
    Type DataType { get; } 
} 

public class MyObject<T> : IMyObject<T>, IMyObject { 
    public Type DataType { 
     get { return typeof(T); } 
    } 
} 

a continuación, la lista podría ser una (la interfaz no genérico) List<IMyObject> y su método de Exist podría tener este aspecto:

public static bool Exist<T>(this IEnumerable source, Type type) { 
    return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type)); 
} 
Cuestiones relacionadas