如何将对象反射为仅在运行时已知的类型
我有一个大问题。
我的问题如下。
我有两种类型: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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只需使用
动态
即可。这将自动使用运行时类型
o
和/或类型T
上存在的任何隐式/显式运算符。 (您的代码不完整,因为您只搜索两者之一。)您的问题的其余部分非常不清楚。你需要重新表述一下。代码也不清楚:变量
castedAssetType
是做什么用的?您只是分配给它,但没有使用它。Just use
dynamic
.This will automatically use any implicit/explicit operators that exist on the run-time type of
o
and/or the typeT
. (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.我找到了解决方案...
我只需向 AssetData 添加一个通用方法“Cast()”即可。我刚刚想到这个想法,因为现在我知道我可以调用通用方法;)
这是解决方案:
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: