System.InvalidCastException: 'Невозможно привести объект типа' System.String 'к типу' Newtonsoft. Json .Linq.JToken '.' - PullRequest
1 голос
/ 30 января 2020

Если я запускаю код:

    object myObject = "abc";
    JToken jToken = (JToken)myObject;

, он компилируется нормально, но выдает crypti c исключение заголовок. Это crypti c, так как можно привести форму String к JToken, что невозможно из-за следующей компиляции и правильной работы:

    String mystring = "abc";
    JToken jToken2 = (JToken)mystring;

Так что мне очень любопытно, почему это происходит?

Конечно, приведенный выше пример немного глуповат, но, возможно, чтобы понять, почему я спрашиваю это, потому что такая же ошибка также возникает в следующей ситуации.

class Program
    public static JToken apply_function(Delegate function, object[] arglist)
    {
        return (JToken)function.DynamicInvoke(arglist);
    }

    static void Main(string[] args)
    {
        Func<string> hello = () => { return "hello world!"; };
        Console.WriteLine(apply_function(hello, new object[0]));
    }
}

Где в реальной ситуации где я хочу использовать apply_function, это ситуация, когда у меня нет контроля над типом возвращаемого значения или типами аргументов делегата, переданных в apply_function. Единственная гарантия, которую я имею, - это то, что делегат будет функцией, которая возвращает что-то, что можно преобразовать в JToken.

Ответы [ 3 ]

3 голосов
/ 30 января 2020

Это на самом деле не актерский состав, а конверсия . Вы можете видеть в документах , что Json. NET определяет преобразование из string в JToken.

Тип stati c в вашем примере - object - не определено преобразование из object в JToken.

Из документов видно, что вы должны попробовать использовать JToken.FromObject.

2 голосов
/ 30 января 2020

Причина, по которой это работает:

string mystring = "abc";
JToken jToken2 = (JToken)mystring;

В том, что JToken имеет явный оператор преобразования из string.

Явные операторы преобразования не учитывают иерархии наследования, как в случае с стандартное приведение, поэтому оно не будет работать с object.

JToken с широким диапазоном пользовательских преобразований, но оно не будет работать с каждым типом, как кажется Вы хотите в apply_function.

Альтернатива JToken.FromObject:

public static JToken apply_function(Delegate function, object[] arglist)
{
    return JToken.FromObject(function.DynamicInvoke(arglist));
}
0 голосов
/ 30 января 2020

Ответ Чарльз Магер заставил меня понять, что тип stati c является проблемой и, следовательно, что:

    public static JToken apply_function(Delegate function, object[] arglist)
    {
        return (dynamic)function.DynamicInvoke(arglist);
    }

также решит проблему. Я предполагаю, что если кто-то хочет, чтобы apply_function вернул JToken, лучше использовать JToken.FromObject. Но не каждый класс может иметь функцию stati c FromObject.

...