Указание универсального типа при доступе к динамическому объекту c # - PullRequest
2 голосов
/ 10 ноября 2010

Возможно ли получить общий результат от динамического объекта.Я пытаюсь создать динамическую оболочку вокруг класса Json.Net JObject.Это работает, но при возврате массива я всегда должен возвращать их как List<object>.Я бы предпочел, чтобы List<T>.

dynamic d = new DynamicJson(json);
var result = d.GetValues<string>();
var d = (string[])d.tags;

DynamicJson - пользовательский класс.Кроме того, когда выполняется вызов с универсальным параметром, как он передается динамическому объекту?

public override bool TryGetMember(GetMemberBinder binder, out object result)
{
   //how do I determine the generic types in this code?
   //can I just do the  casting?
}

Спасибо.

1 Ответ

0 голосов
/ 21 августа 2011

Из того, что я могу сказать, общие параметры никогда не передаются в переопределения TryGetMember() или TryInvokeMember. В документации MSDN показаны только простые имена строк, передаваемые объектами GetMemberBinder и <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.invokememberbinder.aspx" rel="nofollow">GetInvokeBinder</a>.

Самая простая реализация заключается в реализации GetValues<T>() в классе DynamicJSON.

public List<T> GetValues<T>()
{
    Console.WriteLine("Called with generic parameter {0}", typeof(T));
    return new List<T>();
}

Когда я запустил этот простой тест, общим параметром был тип .NET Int32:

dynamic json = new DynamicJSON();
json.GetValues<int>()

Если реализация метода GetValues<T>() неосуществима для вас, вы можете реализовать TryInvokeMember() для возврата метода, в котором реализован <a href="http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.tryconvert.aspx" rel="nofollow">TryConvert()</a>. Когда .NET пытается преобразовать результат GetValues<int>() в List<int>(), ваш переопределенный метод TryConvert() будет вызван с List<int>() как «тип связующего для преобразования».

public class DynamicJSON : DynamicObject
{
    public override bool TryInvokeMember(InvokeMemberBinder binder, Object[] args, out Object result)
    {
        if (binder.Name == "GetValues")
        {
            result = new DynamicValues();
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    private class DynamicValues : DynamicObject
    {
        public override bool TryConvert(ConvertBinder binder, out Object result)
        {
            Console.WriteLine("Converting dynamic values to {0}", binder.Type);

            if (binder.Type == typeof(List<int>))
            {
                result = new List<int>();
                return true;
            }
            else
            {
                result = null;
                return false;
            }
        }
    }
}

public class Test
{
    public static void Main(string[] args)
    {
        dynamic json = new DynamicJSON();
        List<int> values = json.GetValues();
        Console.WriteLine(values.GetType());
    }
}
...