Значение типа 'T' не может быть преобразовано в

Это, скорее всего, новичок, но google неожиданно не дал ответа.

У меня есть этот довольно искусственный метод

    T HowToCast<T>(T t)
    {
        if (typeof(T) == typeof(string))
        {
            T newT1 = "some text";
            T newT2 = (string)t;
        }

        return t;
    }

Исходя из фона на С++, я ожидал, что это сработает. Однако он не может скомпилировать с помощью "Невозможно неявно преобразовать тип" Т "в строку" и "Невозможно преобразовать тип" Т "в строку" для обоих указанных выше назначений.

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

Спасибо!

Ответ 1

Несмотря на то, что внутри блока if компилятор не знает, что T есть string.
Поэтому он не позволяет вам делать бросок. (По той же причине, что вы не можете использовать DateTime до string)

Вам нужно наложить на object (который может передать любой T), а оттуда на string (так как object может быть добавлено к string).
Например:

T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;

Ответ 2

Обе строки имеют одинаковую проблему

T newT1 = "some text";
T newT2 = (string)t;

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

T newT1 = "some text" as T;
T newT2 = t; 

вам не нужно бросать t, так как это уже строка, также нужно добавить ограничение

where T : class

Ответ 3

Если вы проверяете явные типы, почему вы объявляете эти переменные как T?

T HowToCast<T>(T t)
{
    if (typeof(T) == typeof(string))
    {
        var newT1 = "some text";
        var newT2 = t;  //this builds but I'm not sure what it does under the hood.
        var newT3 = t.ToString();  //for sure the string you want.
    }

    return t;
}

Ответ 4

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

public class Foo <T> {

    T var;

    public <T> void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}

Этот код компилирует (примечание T удалено из объявления метода):

public class Foo <T> {

    T var;

    public void doSomething(Class <T> cls) throws InstantiationException, IllegalAccessException {
        this.var = cls.newInstance();
    }

}

Ответ 5

Измените эту строку:

if (typeof(T) == typeof(string))

Для этой строки:

if (t.GetType() == typeof(string))