什么时候在C#中进行泛型定义和实例化的类型检查? [英] When does type checking of generic definitions and instantiations happen in C#?

查看:259
本文介绍了什么时候在C#中进行泛型定义和实例化的类型检查?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,


  • 是否在编译时进行泛型定义的类型检查?


  • 是否在运行时对泛型实例进行类型检查?






以上问题是为了让我理解C#中粗体的引号:

$但是,对于C#泛型,可以将生产者类型(即,诸如
List之类的开放类型)编译为库(例如mscorlib.dll)

这是可行的,因为生产者和产生封闭类型的
消费者之间的综合直到
运行时才真正发生。



为了深入了解为什么会出现这种情况,请再次考虑
C#中的Max方法:

  static T Max< T> (T a,T b)其中T:IComparable< T> 
=> a.CompareTo(b)> 0? a:b;

为什么我们不能像这样实施它?

  static T Max< T> (T a,T b)
=> (a> b→a:b); //编译错误

原因是 Max 需要编译一次,并为所有
可能的值 T 工作。编译无法成功,因为在 T -in的所有值中,
对于> 没有单一含义事实上,每$ T 不是
,甚至有一个> 运算符。


我也有 Java相同的问题。 p>

解决方案

在编译时检查通用定义和实例。此外,他们可以单独检查。与C ++不同,您可能在模板中出现错误,直到您稍后尝试实例化它时才发现,在C#中,当声明本身编译时,将发现泛型声明中的任何编译错误。



C ++所缺乏的魔力是约束。这就是这个例子向你展示的内容。



当你定义一个泛型方法或类时,你可以对类型参数进行约束。这些限制允许实例化,但也决定了你可以在泛型声明的主体中使用哪些操作。



编译声明时,编译器检查你不要对其约束所不允许的类型参数进行任何操作。所以,例如,你会在这里得到一个错误:

  T Foo< T> (T a)=> a.CompareTo(b)中; 

您正试图呼叫 CompareTo a ,其类型为 T 。编译器无法知道用户只会用具有该方法的类型实例化Foo,所以它悲观地认为它可以用一个没有这个类型的类型实例化,并且不能编译这个声明。



当您将其更改为:

  T Foo< T> (T a)其中T:IComparable => a.CompareTo(b)中; 

现在它知道每个T 的实例都必须有一个 CompareTo()方法,因此编译它。



稍后当有人试图用某种类型实例化Foo时,如果类型不实现IComparable,他们得到一个编译错误。由于该方法说您只能使用实现IComparable的类型,编译器确保它们符合该约束。


In C#,

  • does type checking of generic definitions happen at compile time?

  • does type checking of instantiations of generics happen at run time?

Thanks.

The above questions are for me to understand the quotes in bold from C# in a Nutshell:

However, with C# generics, producer types (i.e., open types such as List ) can be compiled into a library (such as mscorlib.dll). This works because the synthesis between the producer and the consumer that produces closed types doesn’t actually happen until runtime.

To dig deeper into why this is the case, consider the Max method in C#, once more:

static T Max <T> (T a, T b) where T : IComparable<T>
  => a.CompareTo (b) > 0 ? a : b;

Why couldn’t we have implemented it like this?

static T Max <T> (T a, T b)
  => (a > b ? a : b);             // Compile error

The reason is that Max needs to be compiled once and work for all possible values of T . Compilation cannot succeed, because there is no single meaning for > across all values of T —in fact, not every T even has a > operator.

I also have the same question for Java.

解决方案

Both generic definitions and instantiations are checked at compile time. Further, they can be checked separately. Unlike C++ where you may have an error in your template that you don't discover until you later try to instantiate it, in C#, any compile errors in a generic declaration will be found when the declaration itself is compiled.

The magic that enables this that C++ lacks is constraints. This is what the example is showing you.

When you define a generic method or class, you can put constraints on the type parameters. Those limit which instantiations are allowed but also determine what operations you can take advantage of in the body of the generic declaration.

When the declaration is compiled, the compiler checks that you don't do anything with a type parameter that its constraints don't allow. So, for example, you'd get an error here:

T Foo<T> (T a) => a.CompareTo(b);

You're trying to call CompareTo on a, whose type is T. The compiler has no way of knowing that a user will only instantiate Foo with types that do have that method, so it pessimistically assumes it could be instantiated with a type that doesn't have that and prevents you from compiling this declaration.

When you change it to:

T Foo<T> (T a) where T : IComparable => a.CompareTo(b);

Now it knows every instantiation of T must have a CompareTo() method, so it compiles this.

Later when someone tries to instantiate Foo with some type, if the type does not implement IComparable, they get a compile error. Since the method says "You can only use me with types that implement IComparable", the compiler ensures they meet that constraint.

这篇关于什么时候在C#中进行泛型定义和实例化的类型检查?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆