В C# определение универсального типа
у меня есть несколько шаблонных объектов, которые реализуют один и тот же интерфейс:
И. Е.
MyObject<datatype1> obj1;
MyObject<datatype2> obj2;
MyObject<datatype3> obj3;
Я хочу сохранить эти объекты в списке... Я думаю, что сделал бы это так:
private List<MyObject<object>> _myList;
затем я хочу создать функцию, которая принимает 1 параметр, являющийся типом данных, чтобы увидеть, существует ли объект, использующий этот тип данных в моем списке.... не знаю, как это сделать. В псевдо-коде это будет:
public bool Exist(DataType T)
{
return (does _myList contain a MyObject<T>?);
}
некоторые Осветление....
мой интерфейс IMyObject<T>
мои объекты MyObject<T>
. У меня новый класс MyObjectManager
что мне нужно иметь список MyObject<T>
хранящиеся внутри. Мне нужна функция, чтобы проверить, если MyObject<T>
есть в этом списке. Тип T
являются типами данных, которые были автоматически сгенерированы с помощью T4.... Классы POCO из моей модели данных сущности.
3 ответов
вы можете сделать общую функцию:
public bool Exists<T>() where T : class {
return _myList.OfType<MyObject<T>>().Any();
}
обратите внимание, что это требует, чтобы вы знали T
во время компиляции.
если все, что у вас есть, это System.Type
объект во время выполнения, вам нужно будет использовать отражение:
public bool Exists(Type t) {
var objectOfT = typeof(MyObject<>).MakeGenericType(t);
return _myList.Any(o => o.GetType() == objectOfT);
}
обратите внимание, однако, что a List<MyObject<object>>
не может провести MyObject<SomeType>
.
Вам нужно изменить список List<object>
, или MyObject
реализовать или наследовать не универсальный тип и сделать список содержать этот тип.
как насчет метода расширения?
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;
}
использование:
bool hasDataType1 = myList.HasAny(typeof(MyObject<datatype1>));
обратите внимание, что если вы не хотите, чтобы ввести typeof(...)
-- т. е., если вы в основном хотите свой Exist
метод только забота об объектах типа MyObject<T>
, Я бы пошел с чем-то вроде ответа Слакса:
public static bool Exist<T>(this IEnumerable source) {
return source.OfType<MyObject<T>>().Any();
}
кроме того, SLaks прав, что вы действительно не можете иметь List<MyObject<object>>
это полно всего, кроме объектов типа MyObject<object>
или некоторый производный класс (и MyObject<datatype1>
, etc. do не выводим из MyObject<object>
-- дженерики так не работают).
другой способ, который я мог бы предложить, чтобы обойти все " вы не можете получить тип универсального класса, используя System.Type
объект без использования отражения " проблема будет такой: сделайте свой MyObject<T>
реализовать не общий интерфейс, как это:
public interface IMyObject {
Type DataType { get; }
}
public class MyObject<T> : IMyObject<T>, IMyObject {
public Type DataType {
get { return typeof(T); }
}
}
тогда ваш список может быть List<IMyObject>
(не общий интерфейс) и ваш Exist
метод может выглядеть так это:
public static bool Exist<T>(this IEnumerable source, Type type) {
return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type));
}
поскольку все они реализуют один и тот же интерфейс, вместо того, чтобы бросать их в объект и вызывать GetType (что может быть дорого), почему бы не добавить свойство к вашему интерфейсу с именем class name (или что-то еще)? Затем вы можете использовать linq для захвата этого свойства. И не забудь!--1-->
using System.Linq;
public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck)
{
return objects.Any(t => t.ObjectName == typeToCheck.ObjectName);
}