Come faccio a determinare il valore di un parametro generico sulla mia istanza di classe

StackOverflow https://stackoverflow.com/questions/113384

  •  02-07-2019
  •  | 
  •  

Domanda

Ho un'interfaccia marcatore definita come

public interface IExtender<T>
{
}

Ho una classe che implementa IExtender

public class UserExtender : IExtender<User>

In fase di esecuzione ricevo il tipo UserExtender come parametro per il mio metodo di valutazione

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

Come posso restituire il mio metodo di valutazione

typeof(User)

basato sulla valutazione del runtime. Sono sicuro che sia coinvolta la riflessione, ma non riesco a romperlo.

(Non ero sicuro di come formulare questa domanda. Spero che sia abbastanza chiaro.)

È stato utile?

Soluzione 3

Sono andato in questo modo basandomi su alcuni dei bocconcini forniti. Potrebbe essere reso più robusto per gestire più argomenti generici sull'interfaccia .... ma non ne avevo bisogno;)

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

Altri suggerimenti

C'è un esempio di ciò che descrivi nella documentazione MSDN per Metodo GetGenericTypeDefinition . Utilizza il metodo GetGenericArguments .

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

Nel tuo esempio penso che vorresti sostituire t con this. Se ciò non funziona direttamente, potresti dover fare qualcosa con Metodo GetInterfaces per enumerare le interfacce correnti sul tuo tipo e quindi GetGenericArguments() dal tipo di interfaccia.

Ho letto la tua domanda in modo completamente diverso rispetto alle altre risposte.

Se la firma di valutazione può essere modificata in:

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

Questo non richiede la modifica del codice chiamante, ma richiede che il parametro sia di tipo IExtender<T>, tuttavia è possibile ottenere facilmente il tipo T:

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

Certamente non è generico come qualcosa che richiede semplicemente un parametro Type, ma questo è un approccio diverso al problema. Si noti inoltre che esistono Considerazioni sulla sicurezza per Reflection [msdn]

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top