392 Stimmen

Casting einer Variablen mit einer Typvariablen

Kann ich in C# eine Variable vom Typ object auf eine Variable des Typs T donde T ist definiert in einem Type variabel?

4voto

krzyski Punkte 296

Wenn es um das Casting auf den Typ Enum geht:

private static Enum GetEnum(Type type, int value)
    {
        if (type.IsEnum)
            if (Enum.IsDefined(type, value))
            {
                return (Enum)Enum.ToObject(type, value);
            }

        return null;
    }

Und Sie werden es auch so nennen:

var enumValue = GetEnum(typeof(YourEnum), foo);

Dies war für mich unerlässlich, wenn ich den Wert des Attributs Beschreibung mehrerer Enum-Typen durch den Wert int erhalten wollte:

public enum YourEnum
{
    [Description("Desc1")]
    Val1,
    [Description("Desc2")]
    Val2,
    Val3,
}

public static string GetDescriptionFromEnum(Enum value, bool inherit)
    {
        Type type = value.GetType();

        System.Reflection.MemberInfo[] memInfo = type.GetMember(value.ToString());

        if (memInfo.Length > 0)
        {
            object[] attrs = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), inherit);
            if (attrs.Length > 0)
                return ((DescriptionAttribute)attrs[0]).Description;
        }

        return value.ToString();
    }

und dann:

string description = GetDescriptionFromEnum(GetEnum(typeof(YourEnum), foo));
string description2 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum2), foo2));
string description3 = GetDescriptionFromEnum(GetEnum(typeof(YourEnum3), foo3));

Alternativ (besserer Ansatz) könnte ein solcher Guss so aussehen:

 private static T GetEnum<T>(int v) where T : struct, IConvertible
    {
        if (typeof(T).IsEnum)
            if (Enum.IsDefined(typeof(T), v))
            {
                return (T)Enum.ToObject(typeof(T), v);
            }

        throw new ArgumentException(string.Format("{0} is not a valid value of {1}", v, typeof(T).Name));
    }

1voto

Ich werde nie verstehen, warum man bis zu 50 Ansehen braucht, um einen Kommentar zu hinterlassen, aber ich musste einfach sagen, dass die Antwort von @Curt genau das ist, was ich gesucht habe und hoffentlich auch jemand anderes.

In meinem Beispiel habe ich ein ActionFilterAttribute, mit dem ich die Werte eines json-Patch-Dokuments aktualisieren wollte. Ich wusste nicht, was das T-Modell für das Patch-Dokument war. Ich musste es in ein einfaches JsonPatchDocument serialisieren und deserialisieren, es ändern und dann, da ich den Typ hatte, serialisieren und deserialisieren, um wieder den Typ zu erhalten.

Type originalType = //someType that gets passed in to my constructor.

var objectAsString = JsonConvert.SerializeObject(myObjectWithAGenericType);
var plainPatchDocument = JsonConvert.DeserializeObject<JsonPatchDocument>(objectAsString);

var plainPatchDocumentAsString= JsonConvert.SerializeObject(plainPatchDocument);
var modifiedObjectWithGenericType = JsonConvert.DeserializeObject(plainPatchDocumentAsString, originalType );

0voto

marianop Punkte 99

Wenn Sie Objekte zur Laufzeit casten müssen, ohne den Zieltyp zu kennen, können Sie Reflection verwenden, um einen dynamischen Konverter zu erstellen.

Dies ist eine vereinfachte Version (ohne Zwischenspeicherung generierte Methode):

    public static class Tool
    {
            public static object CastTo<T>(object value) where T : class
            {
                return value as T;
            }

            private static readonly MethodInfo CastToInfo = typeof (Tool).GetMethod("CastTo");

            public static object DynamicCast(object source, Type targetType)
            {
                return CastToInfo.MakeGenericMethod(new[] { targetType }).Invoke(null, new[] { source });
            }
    }

dann können Sie es aufrufen:

    var r = Tool.DynamicCast(myinstance, typeof (MyClass));

-1voto

user2008563 Punkte 15
public bool TryCast<T>(ref T t, object o)
{
    if (
        o == null
        || !typeof(T).IsAssignableFrom(o.GetType())
        )
        return false;
    t = (T)o;
    return true;
}

-3voto

Harm Salomons Punkte 11

Noch sauberer:

    public static bool TryCast<T>(ref T t, object o)
    {
        if (!(o is T))
        {
            return false;
        }

        t = (T)o;
        return true;
    }

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X