在函数的这一部分(.NET 2.0)中:
public void AttachInput<T>(T input) where T : struct
{
if (input is int)
{
Inputs.Add((int)input);
}
}
Run Code Online (Sandbox Code Playgroud)
编译器显示错误"无法将类型'T'转换为'int'.
所以,我使用Convert.ToInt32()哪个工作 - 但是它是否包装input到一个对象?有更好的解决方案吗?谢谢
编辑1:取消与问题相关的不必要的东西
编辑2:深入研究泛型,在我看来,Convert.ToInt32当T已经是一个int时,没有对一个对象的装箱,而它的int重载就是被调用的那个.
如果这是真的,那么这些Convert方法在我看来是最好的选择
对于类型安全和避免装箱,您唯一的选择是输入类型的特定重载int:
public void AttachInput(int input)
{
Inputs.Add(input);
}
Run Code Online (Sandbox Code Playgroud)
更新:
OP用一个理论更新了这个问题:
深入研究泛型,在我看来,当T已经是一个int时,Convert.ToInt32对一个对象没有装箱,而它的int重载就是被调用的那个.
这是不对的,一个简单的测试可以证明它.假设我们编写自己的一组重载只是为了检测哪一个被调用:
public static class OverloadTest
{
public static void Foo(int x)
{
Console.WriteLine("Foo(int)");
}
public static void Foo(bool x)
{
Console.WriteLine("Foo(bool)");
}
public static void Foo(object x)
{
Console.WriteLine("Foo(object)");
}
}
Run Code Online (Sandbox Code Playgroud)
现在我们编写一个通用方法来模拟问题中的那个:
static void CallTheRightFoo<T>(T value) where T : struct
{
OverloadTest.Foo(value);
}
Run Code Online (Sandbox Code Playgroud)
理论上,因为CLR/JIT将为每种值类型生成特定版本的方法,所以它可以选择特定的过载,int因为它可用.
所以这是测试:
struct Test { } // in order to test a user-defined value type
static void Main(string[] args)
{
CallTheRightFoo(1);
CallTheRightFoo(true);
CallTheRightFoo(new Test());
}
Run Code Online (Sandbox Code Playgroud)
输出是:
Foo(object)
Foo(object)
Foo(object)
Run Code Online (Sandbox Code Playgroud)
要将其与Convert.ToInt32您的通用代码相关联,您将始终调用接受的重载,object因此该值将被装箱,然后必须在内部取消装箱Convert.ToInt32(这也必须先检查它是什么类型).
虽然重申所有这一点背后的重要一点:虽然与不这样做相比,装箱/拆箱比较昂贵,但与你的代码所做的任何实际工作相比,它的成本可能微不足道.所以我不会过分担心它的成本,直到你可以证明它是使用你的库的应用程序的真实模型的真正负担.