我可以不使用通用吗?

时间:2014-04-15 08:10:29

标签: c# generics

void LoadParameters<TValue>(Type i1, TValue i2)
        where TValue : i3;
{    
Tvalue A;

看到这段代码,我稍微修改了它的专有

我在想是否与

相同
void LoadParameters(Type i1, TValue i2)
{
i3 A;

由于开发人员已经知道A是i3类型,而不只是在代码中指定了吗?

4 个答案:

答案 0 :(得分:2)

你的假设是错误的:

  

由于开发人员已经知道A属于i3类型,而不只是在代码中指定了吗?

TValue可以是i3 或任何派生!如果i3是一个接口,您可以像这样调用方法:

LoadParameters<i3>(...);

或使用任何实现i3的类型:

class Foo : i3 { }
interface IBar { }
class FooBar : Foo, IBar { }

LoadParameters<Foo>(...);     // Okay
LoadParameters<IBar>(...);    // fails, because IBar does not inherit from i3!
LoadParameters<FooBar>(...);  // Okay, because FooBar inherits from Foo that implements i3!

如果您错误地调用LoadParameters(如第二个示例中所示),则编译器会抱怨它。如果不使用约束,您将遇到运行时异常,这些异常更难调试。因此,通过支持开发人员以正确的方式调用方法,而不是遇到异常并让他修复代码,约束有助于使代码更具可读性。

答案 1 :(得分:1)

在编译时是否会推断出一些void LoadParameters<TValue>,因此您可以利用泛型类型

  • 编译时间检查
  • 动态静态意味着您可以使用通用算法所需的任何类型

考虑第一个版本,因为您可以使用相同的通用代码加载任何类型的参数,而无需在每次需要获取新类型时创建更多版本

答案 2 :(得分:0)

解释了C#中类型参数的限制here。在您的情况下,TValue可以采用在第一种情况下i3派生的任何类型,其中第二种情况A将完全属于i3类型。

答案 3 :(得分:0)

从调用者的角度来看,你是对的 - 实际上它写得非常相似:

1. LoadParameters<TValue>( Type v1, TValue v2 ) where TValue : Interface3;
  or
2. LoadParameters( Type v1, Interface3 v2 );

它没有什么区别 - 当调用method2时,编译器将检查提供的参数是否可以转换为Interface3(与泛型类型参数完全相同),如果你想要确定你的Object的语法糖不仅可以使用Interface3,而且可以从某个子类同样调用:

1. LoadParameters<Foo>( v1, v2 );
2. LoadParameters( v1, (Foo)ve ); // Explicit Casting provides static type-checking

soooo ....区别在哪里?为什么我们甚至需要泛型?

答案不在于签名,而在于Method ...想象一下,你想在Method中构造一个新的Object,或者创建一个通用的List。 - 使用Generic TValue ,您可以轻松调用TValue-&gt; newInstance()或创建List。想象一下Generic类型作为第三个参数,你可以获得一个额外的Class-Information,它不需要是v2的运行时类,但v2必须可以转换为该类......