开发者

Howto reflect object into an only at runtime known type

i have a little big problem.

My problem is the following.

I´ve got two types: AssetData and AssetData. They are basicly the same, but not inherited.

Now i have i know a property with the Type "AssetData", and i have a object of type AssetData (containing a Texture2D object).

Now i want to cast the AssetData object into the AssetData object. Because i don´t know the generic parameter, AssetData has now operator for that kind of cast, but AssetData is able to cast to AssetData.

I tried and tried what i could do to solve it, but i have no more ideas.

Here´s my situation: I´ve got a type of a property, i have a AssetData with the same object, but i must set the AssetData to the property - so i have to set "AssetData", not AssetData.

Here´s my code. I can´t hardcode it, because it would be to much to change after adding new types. That´s my latest try. It nearly works, but has the problem that the cast does not work, because there´s no operator of AssetData ...

foreach (PropertyInfo pinf in comp.GetType().GetProperties())
            {
                for (int i = 0; i < cdata.PInf.Count; i++)
                {
                    if (cdata.PInf[i] != pinf.Name) continue;

                    AssetData assetData = new AssetData
                                              {
                                                  AssetName = cdata.AN[i],
                                                  AssetType = Type.GetType(cdata.AT[i], true)
                                              };
                    Application.Game.GetSystem<ContentManager>().LoadContent(ref assetData);

                    if (pinf.PropertyType.IsGenericType)
                    {
                        MethodInfo method = typeof (DynamicCast).GetMethod("Cast").GetGenericMethodDefinition().MakeGenericMethod(
                                assetData.AssetType);

                        Type castedAssetType =
                            pinf.PropertyType.GetGenericTypeDefinition().MakeGenericType(assetData.AssetType);

                        dynamic castedAsset = method.Invoke(typeof (DynamicCast), new[] {assetData});

                        pinf.SetValue(comp, castedAsset, null);
                    }
                }
            }
        }

And here´s the method of "DynamicCast" - which i found on an blog. This also doesn´t work ...

    public static class DynamicCast
{
    public static T Cast<T>(object o)
    {
        Type ot = o.GetType();
        MethodInfo meth = GetMethod(ot, "op_Implicit", typeof(T),
            BindingFlags.Static | BindingFlags.Public);
        if (meth == null)
        {
            meth = GetMethod(ot, "op_Explicit", typeof(T),
                BindingFlags.Static | BindingFlags.Public);
        }

        if (meth == null) throw new InvalidCastException("Invalid Cast.");

        return (T) meth.Invoke(null, new[] {o});
    }

    public static MethodInfo GetMethod(Type toSearch, string methodName,
        Type returnType, BindingFlags bindingFlags)
    {
        return Array.Find(
            toSearch.GetMethods(开发者_如何学编程bindingFlags),
            inf => ((inf.Name == methodName) && (inf.ReturnType == returnType)));
    }
}

The problem is, that i must create an AssetData object (in this case), and set it as value for the property. But the object is clear, so i must cast AssetData´s "Asset"-property to the "AssetData"´s. Both are the same type, but one is "object" and one "T" (Texture2D).

How can i cast this?

Thanks a lot! I´m workin on this since the midday ...


Just use dynamic.

public static class DynamicCast
{
    public static T Cast<T>(object o)
    {
        return (T) (dynamic) o;
    }
}

This will automatically use any implicit/explicit operators that exist on the run-time type of o and/or the type T. (Your code is incomplete because you’re searching only one of the two.)

The rest of your question is extremely unclear. You need to rephrase it. The code is also unclear: what is the variable castedAssetType for? You are only assigning to it but then not using it.


I got the solution...

I just had to add an generic method "Cast()" to AssetData. I just came on this idea, because now i know i can invoke a generic method ;)

Here´s the solution:

if (pinf.PropertyType.IsGenericType)
{
    MethodInfo method =
        assetData.GetType().GetMethod("Cast").GetGenericMethodDefinition().MakeGenericMethod(
            assetData.AssetType);

    dynamic castedAsset = method.Invoke(assetData, null);

    pinf.SetValue(comp, castedAsset, null);
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜