我可以不使用泛型吗

本文关键字:泛型 我可以 | 更新日期: 2023-09-27 17:58:26

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

看到这个代码,我稍微修改了一下,因为它是的专利

我在想它是否和一样

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

既然开发人员已经知道A是i3类型的,那么哪里不只是在代码中指定呢?

我可以不使用泛型吗

您的假设是错误的:

既然开发人员已经知道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(如第二个示例(,编译器会抱怨它。如果不使用约束,您将遇到运行时异常,这些异常更难调试。因此,通过支持开发人员以正确的方式调用方法,而不是遇到异常并让他修复代码,约束有助于提高代码的可读性。

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

  • 编译时检查
  • 动态而非静态意味着您可以在通用算法中使用任何类型

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

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

从调用者的角度来看,你是对的——实际上写完全一样

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

这并没有什么区别——当调用方法2时,编译器会检查所提供的参数是否可转换到接口3(与泛型类型参数完全相同(,如果你想确保你的对象不仅是接口3,而且来自某个子类,你可以同样调用:

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

soooo。。。。区别在哪里?为什么我们甚至需要仿制药?

答案不在于签名,而在于方法。。。想象一下,你想在方法中构造一个新的Object,或者创建一个泛型List使用GenericTValue,您可以轻松地调用TValue->newInstance((或创建一个List。将Generic类型想象为第三个参数,在这里您可以获得一个额外的Class Information,它不需要是v2的运行时类,但v2必须可转换到该类。。。