Как определить значение универсального параметра в моем экземпляре класса - PullRequest
1 голос
/ 22 сентября 2008

У меня есть интерфейс маркера, определенный как

public interface IExtender<T>
{
}

У меня есть класс, который реализует IExtender

public class UserExtender : IExtender<User>

Во время выполнения я получаю тип UserExtender в качестве параметра для моего метода оценки

public Type Evaluate(Type type) // type == typeof(UserExtender)

Как заставить мой метод Evaluate возвращать

typeof(User)

на основе оценки времени выполнения. Я уверен, что отражение вовлечено, но я не могу его взломать.

(Я не знал, как сформулировать этот вопрос. Надеюсь, он достаточно ясен.)

Ответы [ 3 ]

1 голос
/ 22 сентября 2008

Я пошел по этому пути, основываясь на некоторых примерах. Его можно сделать более надежным для обработки нескольких общих аргументов интерфейса ... но мне это не нужно;)

private static Type SafeGetSingleGenericParameter(Type type, Type interfaceType)
{
    if (!interfaceType.IsGenericType || interfaceType.GetGenericArguments().Count() != 1)
        return type;

    foreach (Type baseInterface in type.GetInterfaces())
    {
        if (baseInterface.IsGenericType &&
                baseInterface.GetGenericTypeDefinition() == interfaceType.GetGenericTypeDefinition())
        {
            return baseInterface.GetGenericArguments().Single();
        }
    }

    return type;
}
1 голос
/ 22 сентября 2008

Я читаю ваш вопрос совершенно иначе, чем другие ответы.

Если подпись оценки может быть изменена на:

public Type Evaluate<T>(IExtender<T> it)
{
    return typeof(T);
}

Это не требует изменения кода вызова, но требует, чтобы параметр имел тип IExtender<T>, однако вы можете легко получить тип T:

// ** compiled and tested    
UserExtender ue = new UserExtender();
Type t = Evaluate(ue);

Конечно, это не так обобщенно, как просто принятие параметра Type, но это другой подход к проблеме. Также обратите внимание, что существуют соображения безопасности для отражения [msdn]

1 голос
/ 22 сентября 2008

Существует пример того, что вы описываете в документации MSDN для метода GetGenericTypeDefinition . Используется метод GetGenericArguments .

Type[] typeArguments = t.GetGenericArguments();
Console.WriteLine("\tList type arguments ({0}):", typeArguments.Length);
foreach (Type tParam in typeArguments)
{
    Console.WriteLine("\t\t{0}", tParam);
}

В вашем примере, я думаю, вы захотите заменить t на this. Если это не сработает напрямую, вам может понадобиться что-то сделать с помощью метода GetInterfaces для перечисления текущих интерфейсов вашего типа, а затем GetGenericArguments() из типа интерфейса.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...