[英]Value of type 'T' cannot be converted to
這很可能是一個新手問題,但 google 出人意料地沒有提供答案。
我有這個相當人為的方法
T HowToCast<T>(T t)
{
if (typeof(T) == typeof(string))
{
T newT1 = "some text";
T newT2 = (string)t;
}
return t;
}
來自 C++ 背景,我希望這能奏效。 但是,對於上述兩個分配,它無法使用“無法將類型 'T' 隱式轉換為字符串”和“無法將類型 'T' 轉換為字符串”進行編譯。
我要么在概念上做錯了,要么只是語法錯誤。 請幫我解決這個問題。
謝謝!
即使它在if
塊內,編譯器也不知道T
是string
。
因此,它不允許您進行投射。 (出於同樣的原因,您不能將DateTime
為string
)
您需要轉換為object
,(任何T
都可以轉換為),然后從那里轉換為string
(因為object
可以轉換為string
)。
例如:
T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;
兩條線都有同樣的問題
T newT1 = "some text";
T newT2 = (string)t;
編譯器不知道 T 是一個字符串,因此無法知道如何分配它。 但是既然你檢查過了,你就可以用
T newT1 = "some text" as T;
T newT2 = t;
您不需要強制轉換 t 因為它已經是一個字符串,還需要添加約束
where T : class
我知道 OP 在這個問題中從通用解析器發布的類似代碼。 從性能角度來看,您應該使用Unsafe.As<TFrom, TResult>(ref TFrom source)
,它可以在System.Runtime.CompilerServices.Unsafe NuGet 包中找到。 它避免了在這些場景中對值類型進行裝箱。 我還認為Unsafe.As
導致 JIT 生成的機器代碼少於兩次轉換(使用(TResult) (object) actualString
),但我還沒有檢查出來。
public TResult ParseSomething<TResult>(ParseContext context)
{
if (typeof(TResult) == typeof(string))
{
var token = context.ParseNextToken();
string parsedString = token.ParseToDotnetString();
return Unsafe.As<string, TResult>(ref parsedString);
}
else if (typeof(TResult) == typeof(int))
{
var token = context.ParseNextToken();
int parsedInt32 = token.ParseToDotnetInt32();
// This will not box which might be critical to performance
return Unsafe.As<int, TResult>(ref parsedInt32);
}
// other cases omitted for brevity's sake
}
Unsafe.As
將被具有高效機器代碼指令的 JIT 取代,正如您在官方 CoreFX 存儲庫中所見:
如果您要檢查顯式類型,為什么要將這些變量聲明為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;
}
如果您的類和方法都有通用聲明,您也會收到此錯誤。 例如,下面顯示的代碼給出了這個編譯錯誤。
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();
}
}
改變這一行:
if (typeof(T) == typeof(string))
對於這一行:
if (t.GetType() == typeof(string))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.