如何将对象反射为仅在运行时已知的类型

发布于 2024-10-31 15:15:14 字数 2926 浏览 1 评论 0原文

我有一个大问题。
我的问题如下。

我有两种类型:AssetData 和 AssetData。它们基本相同,但不是继承的。
现在我知道一个类型为“AssetData”的属性,并且我有一个 AssetData 类型的对象(包含一个 Texture2D 对象)。

现在我想将 AssetData 对象转换为 AssetData 对象。因为我不知道通用参数,所以 AssetData 现在有用于此类转换的运算符,但 AssetData 能够转换为 AssetData。

我尝试了很多办法来解决它,但我没有更多的想法。

这是我的情况:我有一个属性类型,我有一个具有相同对象的 AssetData,但我必须将 AssetData 设置为该属性 - 所以我必须设置“AssetData”,而不是 AssetData。

这是我的代码。我无法对其进行硬编码,因为添加新类型后需要进行太多更改。这是我最近的尝试。它几乎可以工作,但有一个问题,即强制转换不起作用,因为没有 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);
                    }
                }
            }
        }

这是我在博客上找到的“DynamicCast”方法。这也不起作用...

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

问题是,我必须创建一个 AssetData 对象(在本例中),并将其设置为属性的值。但对象是明确的,所以我必须将 AssetData 的“Asset”属性转换为“AssetData”。两者是相同的类型,但一个是“object”,一个是“T”(Texture2D)。

我怎样才能投射这个?

多谢!我从中午就开始做这件事......

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 ...

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

困倦 2024-11-07 15:15:14

只需使用动态即可。

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

这将自动使用运行时类型 o 和/或类型 T 上存在的任何隐式/显式运算符。 (您的代码不完整,因为您只搜索两者之一。)

您的问题的其余部分非常不清楚。你需要重新表述一下。代码也不清楚:变量 castedAssetType 是做什么用的?您只是分配给它,但没有使用它。

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.

梦回梦里 2024-11-07 15:15:14

我找到了解决方案...

我只需向 AssetData 添加一个通用方法“Cast()”即可。我刚刚想到这个想法,因为现在我知道我可以调用通用方法;)

这是解决方案:

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

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文