Как отразить объект во время выполнения только известного типа - PullRequest
1 голос
/ 10 апреля 2011

У меня маленькая проблема.
Моя проблема в следующем.

У меня есть два типа: 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».Оба имеют одинаковый тип, но один - "объект", а другой - "T" (Texture2D).

Как я могу разыграть это?

Большое спасибо!Я работаю над этим с полудня ...

Ответы [ 2 ]

1 голос
/ 10 апреля 2011

Я получил решение ...

Мне просто нужно было добавить универсальный метод Cast () в AssetData. Я просто пришел к этой идее, потому что теперь я знаю, что могу вызвать универсальный метод;)

Вот решение:

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);
}
1 голос
/ 10 апреля 2011

Просто используйте dynamic.

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

При этом будут автоматически использоваться любые неявные / явные операторы, существующие для типа выполнения o и / или типа T. (Ваш код неполный, потому что вы ищете только один из двух.)

Остальная часть вашего вопроса крайне неясна. Вы должны перефразировать это. Код также неясен: для чего нужна переменная castedAssetType? Вы только назначаете это, но затем не используете его.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...