2015-08-14 6 views
6

Domanda simile: Passing int list as a parameter to a web user control
Esiste un esempio simile per il tipo enum?

Sto creando un controllo personalizzato asp.net in cui voglio passare l'elenco separato da virgole delle enumerazioni come proprietà.
Sto scrivendo un TypeConverter per convertire valori stringa separati da virgola a Elenco di enum.

Nel metodo ConvertTo,
Come creare l'oggetto InstanceDescriptor per l'elenco di enum?

mio codice attuale è la seguente:Come creare InstanceDescriptor per l'elenco di enum?

//enum 
public enum MyEnum {Hello, World} 

//main method 
List<MyEnum> list = new List<MyEnum>(); 
list.Add(MyEnum.Hello); 
list.Add(MyEnum.World); 
ConstructorInfo constructor = typeof(List<MyEnum>).GetConstructor(Type.EmptyTypes); 
InstanceDescriptor idesc = new InstanceDescriptor(constructor, list); 

Questo riesce con il messaggio

Length mismatch 

Mi chiedo perché

risposta

2

L'errore "Lunghezza non corrispondente" si verifica perché si recupera la default List<T> constructor, che ha ZERO argomenti, e quindi vi chiedo InstanceDescriptor a chiamare quel costruttore con DUE argomenti, MyEnum.Hello e MyEnum.World.

Si potrebbe pensare che si potrebbe usare la alternate List<T> constructor che accetta un singolo argomento IEnumerable<T>:

ConstructorInfo constructor = 
    typeof(List<MyEnum>).GetConstructor(new[] { typeof(IEnumerable<MyEnum>) }); 
InstanceDescriptor idesc = new InstanceDescriptor(constructor, new[] { list }); 

Questo rende InstanceDescriptor felice, ma purtroppo, vi accorgerete che ASP.NET ora getta NullReferenceException invece (lo stesso nello question you linked to) perché ASP.NET non sa come gestire i parametri IEnumerable<T>.

Ecco due modi per risolvere il problema.

Soluzione 1: Cambia il tuo controllo personalizzato e il vostro convertitore di tipi da utilizzare al posto di MyEnum[]List<MyEnum>. Funziona perché ASP.NET è in grado di gestire gli array.

Soluzione 2: Creare un metodo di supporto statica che crea un List<MyEnum> da un array:

public static List<MyEnum> ToList(MyEnum[] values) 
{ 
    return new List<MyEnum>(values); 
} 

poi cambiare convertitore di tipi per creare un InstanceDescriptor che chiama il metodo di supporto, passando la vostra lista come un array:

MethodInfo method = typeof(MyEnumListConverter).GetMethod("ToList"); 
InstanceDescriptor idesc = new InstanceDescriptor(method, new[] { list.ToArray() }); 
2

L'elenco dovrebbe essere un insieme vuoto perché constructor è il senza parametri constructor il tuo codice dovrebbe apparire così:

List<MyEnum> list = new List<MyEnum>(); 
ConstructorInfo constructor = typeof(List<MyEnum>).GetConstructor(Type.EmptyTypes); 
InstanceDescriptor idesc = new InstanceDescriptor(constructor, list); 

Oppure utilizzare un null constructor:

ConstructorInfo constructor = 
    typeof(List<MyEnum>).GetConstructor(BindingFlags.ExactBinding, null,Type.EmptyTypes, null); 

Ciò significa: il campo EmptyTypes utilizzato in una delle GetConstructor metodi per ottenere un constructor che non accetta parametri.

+0

restituisce oggetto 'costruttore' null –

+1

controlla la mia risposta aggiornata. –