这可能是一个新手问题,但谷歌出人意料地没有提供答案。
我有一种相当人工的方法
T HowToCast<T>(T t)
{
if (typeof(T) == typeof(string))
{
T newT1 = "some text";
T newT2 = (string)t;
}
return t;
}
来自C++的背景,我希望这能起作用。但是,对于上述两种赋值,它都无法编译为“无法隐式将类型'T‘转换为字符串”和“无法将类型'T’转换为字符串”。
我要么在做一些概念上错误的事情,要么就是语法错误。请帮我把这个整理好。
谢谢!
发布于 2010-11-04 06:57:15
即使它在if
块中,编译器也不知道T
是string
。
因此,它不允许您进行强制转换。(原因与您不能将DateTime
转换为string
的原因相同)
您需要转换为object
(任何T
都可以转换为它),并从那里转换为string
(因为object
可以转换为string
)。
例如:
T newT1 = (T)(object)"some text";
string newT2 = (string)(object)t;
发布于 2010-11-04 07:03:56
这两条线路都有相同的问题
T newT1 = "some text";
T newT2 = (string)t;
编译器不知道T是一个字符串,因此无法知道如何赋值。但是既然你已经检查过了,你就可以用下面的命令
T newT1 = "some text" as T;
T newT2 = t;
您不需要强制转换t,因为它已经是一个字符串,还需要添加约束
where T : class
发布于 2019-10-27 19:57:38
我知道OP在这个问题中从泛型解析器中发布的类似代码。从性能的角度来看,您应该使用Unsafe.As<TFrom, TResult>(ref TFrom source)
,它可以在System.Runtime.CompilerServices.Unsafe NuGet包中找到。在这些场景中,它避免了值类型的装箱。我还认为与两次转换(使用(TResult) (object) actualString
)相比,Unsafe.As
产生的机器代码更少,但我还没有验证过这一点。
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
}
正如您在官方CoreFX代码库中看到的那样,Unsafe.As
将被JIT替换为高效的机器代码指令:
https://stackoverflow.com/questions/4092393
复制相似问题