2016-06-29 14 views
0

I diese Codezeile haben:C#: strings Converting ENUM und nicht-ENUM mit der gleichen Funktion

obj.Properties.ToList().ForEach(p => parameters.Add(Convert.ChangeType(p, ctor.GetParameters()[parameters.Count].ParameterType))); 

obj.Properties ist ein String-Array (string[]) und parameters ist eine Liste von Objekten (List<object>) . Ich möchte eine neue Instanz einer Klasse erstellen, für die ich einen Konstruktor (ctor) ausgewählt habe, der so viele Parameter wie viele Strings in meinem obj.Properties Array hat.

Um den Konstruktor aufzurufen, muss ich die Zeichenfolgen in Typen umwandeln, die der Konstruktor benötigt (wie Sie meinen Versuch oben sehen können). Das funktioniert für int und bool, aber der Konstruktor hat auch einen enum Parameter, und wenn mein Code versucht, die Zeichenfolge in eine Enum zu konvertieren, bekomme ich InvalidCastException.

Ich lese ein SOF answer, in dem Enum.Parse stattdessen vorgeschlagen wird, aber ich möchte dies in einer Zeile tun (hängt nicht davon ab, ob es eine Enumeration ist oder nicht). So habe ich die Lösung der verknüpften Antwort:

public static T MyConvert<T>(String value) 
{ 
    if (typeof(T).IsEnum) 
    return (T)Enum.Parse(typeof(T), value); 

    return (T)Convert.ChangeType(value, typeof(T)); 
} 

Und dann:

obj.Properties.ToList().ForEach(p => parameters.Add(MyConvert< ctor.GetParameters()[parameters.Count].ParameterType>(p))); 

Aber ich habe einen Fehler: Operator '<' cannot be applied to operands of type 'method group' and 'Type'

Ich habe auch versucht

Type type = ctor.GetParameters()[parameters.Count].ParameterType; 
obj.Properties.ToList().ForEach(p => parameters.Add(MyConvert<type>(p))); 

Aber ich erhalten: 'type' is a variable but is used like a type

Dieses

ist eine Arbeitslösung:

obj.Properties.ToList().ForEach(p => 
{ 
    if (ctor.GetParameters()[parameters.Count].ParameterType.IsEnum) 
    { 
     parameters.Add(Enum.Parse(ctor.GetParameters()[parameters.Count].ParameterType, p)); 
    } 
    else 
    { 
     parameters.Add(Convert.ChangeType(p, ctor.GetParameters()[parameters.Count].ParameterType)); 
    } 
}); 

Aber ist es eine Möglichkeit, den gleichen Code für Aufzählungen und nicht-Aufzählungen zu benutzen? Also, ich suche nach einer Lösung ohne if(...IsEnum) im ForEach.

+0

Können Sie zeigen, wie Sie den Konstruktor aufrufen? –

+0

@MatteoUmili ctor.Invoke (Parameter.ToArray()) – szkup

Antwort

0

Ich habe eine Lösung gefunden: die MyConvert-Funktion nicht generisch zu machen (so dass der genaue Typ in der Laufzeit genügt, anstatt in der Kompilierzeit).

public static object MyConvert(String value, Type T) 
{ 
    if (T.IsEnum) 
     return Enum.Parse(T, value, true); 

    return Convert.ChangeType(value, T); 
} 

Und dann:

obj.Properties.ToList().ForEach(p => parameters.Add(Parse(p, ctor.GetParameters()[parameters.Count].ParameterType)));