Это, скорее всего, новичок, но 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))