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> сохраненный в. Мне нужна функция, чтобы проверить если a MyObject<T> существует в том списке. Тип T типы данных, которые были автоматически сгенерированы с помощью T4.... ПОСТЕПЕННО классы от моей Модели данных Объекта.

6
задан Chris Klepeis 27 May 2010 в 17:59
поделиться

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);
}

Обратите внимание, однако, что List > не может содержать MyObject .
Вам нужно изменить список на List или сделать MyObject реализацией или наследованием неуниверсального типа и сделать список содержащим этот тип.

6
ответ дан 17 December 2019 в 00:04
поделиться

Как насчет метода расширения?

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 , я бы сказал что-то вроде ответа SLaks:

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

Кроме того, SLaks прав в том, что у вас действительно не может быть List > , заполненный чем-либо, кроме объектов типа MyObject или некоторого производного класса (и MyObject и т. Д. Не не унаследован от MyObject - дженерики так не работают).

Я мог бы предложить еще один способ обойти проблему «невозможно получить тип универсального класса с помощью объекта System.Type без использования отражения»: сделайте свой ] MyObject реализует неуниверсальный интерфейс, например:

public interface IMyObject {
    Type DataType { get; }
}

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

Тогда ваш список может быть List (неуниверсальный интерфейс) и вашим Exist метод может выглядеть так:

public static bool Exist<T>(this IEnumerable source, Type type) {
    return source.OfType<IMyObject>().Any(x => x.DataType.Equals(type));
}
1
ответ дан 17 December 2019 в 00:04
поделиться

Поскольку все они реализуют один и тот же интерфейс, вместо того, чтобы преобразовывать их в объект и вызывать GetType (что может быть дорогостоящим), почему бы не добавить в интерфейс свойство, называемое именем класса (или чем-то еще)? Затем вы можете использовать linq, чтобы получить это свойство. И не забывайте с помощью System.Linq

using System.Linq;

public bool Exist(List<IMyInterface> objects, IMyInterface typeToCheck)
{
   return objects.Any(t => t.ObjectName == typeToCheck.ObjectName);
}
0
ответ дан 17 December 2019 в 00:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: