English 中文(简体)
为什么要对后代类型重新宣布一般性限制?
原标题:Why do generic type restrictions have to be redeclared on descendant types?

在C#中,考虑到诸如:

interface IGenericType<T> where T : new()

后代,例如:

class GenericTypeImplementation<U> : IGenericType<U>

为什么我们需要明确限制一般类型的<代码>U,并对父母类型的所有限制?

class GenericTypeImplementation<U> : IGenericType<U> where U : new()

我有权指出,问题在于编纂者计算限制的结合?

interface IGenericType<T> where T : new()
interface IGenericType2<T> where T : SomeOtherType
class GenericTypeImplementation<U> : IGenericType<U>, IGenericType2<U>
/* Hypothesis: Compiler can t infer U must be "SomeOtherType + new()" */
最佳回答

我认为,汇编者could足以从理论上推断限制。 但shouldn t就是如此聪明,因为过于聪明的编纂者有时很危险。 研制者总是需要明确/明确的定义。 见这一设想:

(1) 有一个<条码>内联网;T>T:新(

(2) a class Foo<T>:IFoo<T>new( 限值由汇编者自动添加(brilliant!)

(3) 类别<代码> Foo<T>是整个项目的一个非常基本类别,class A<T>: Foo<T>,然后class B<T> : A<T>

(4) 既然另一个开发商很难认识到存在这种限制,他会发现这一类别的定义,而将编篡错误(容易被接受)。 但是,如果加以思考,它们会是什么? 有时该方案是正确的,因为数据符合事故限制。

问题回答

汇编者能够推断,U必须可兑换到一些其他类型,而且必须有违约构造者。 它将造成每个制约因素的汇编错误:

Error   1   The type  U  must have a public parameterless constructor in order to use it as parameter  T  in the generic type or method  ....IGenericType<T> 
Error   2   The type  U  must be convertible to  ....SomeOtherType  in order to use it as parameter  T  in the generic type or method  ....IGenericType2<T> 

这样做的还有,只有其中一个接口得到实施。 该课程必须成功实施两个接口,以便汇编:

class GenericTypeImplementation<U> : IGenericType<U>, IGenericType2<U>
    where U : SomeOtherType, new()
{...}

或非基因类:

class GenericTypeImplementation : IGenericType<SomeType>, IGenericType2<SomeOtherType>
{...}

标明一个类别作为接口的实施,不是具体限制某类通用参数的一种方法;而是要求这些限制存在于新的类型参数上,或者以供应类型满足。

也许你可以这样认为:一个接口是一套有限的班级,一个通用班级也受到限制。 通用接口是一套有限的通用类别。 当你说一个通用类别具有通用接口时,你正在请汇编者“这一通用类别是否严格在这一通用接口规定的范围之内?” 你不单把他们混为一谈,把它当作又受限制的课堂。

由于一般类型的限制属于定义类别(U,请参看您的事例)的类型参数,因此从《公约》的角度来看,与接口的类型参数不同。

The type parameter of the class need not be the actual type parameter of the interface. It need not even be a simple type, as in:

class Implementation<T> : IGenericType<List<T>> { /* ... */ }

In this case, the compiler recognizes that List<T> satisfies the constraint, and so no further specification is necessary. But without such knowledge about the generic type parameter, the compiler requires you to declare it explicitly.

将这种做法与通用方法的类似但并非相同的行为相比较是有启发性的。 如同实施接口的班级一样,在申报中必须具体说明这类限制。 有一个明显的例外:如果执行明确的话。 事实上,如果你试图重新实施这些限制,汇编者将产生错误。

例如,考虑到接口

interface ISomething {
    void DoIt<T>() where T : new();
}

执行这一接口的两种正确方式是:

class OneThing : ISomething {
    public void DoIt<T>() where T : new() { }
}

class OtherThing : ISomething {
    void ISomething.DoIt<T>() { }
}

排除<代码>第1版中的限制,或在<代码>中填报。 其他Thing产生汇编时错误。 为什么在第一次执行中,而不是在第二次执行中,我们需要限制? d 出于上文提及的对接口的类型限制的同样原因:在第一次实施过程中,<代码>T<>/code>与接口方法的类型参数没有关系,因此,必须明确对应接口方法的方法。 在第二次实施过程中,我们明确宣布接口,这意味着“参数”<代码>与接口中使用的参数完全相同。





相关问题
Anyone feel like passing it forward?

I m the only developer in my company, and am getting along well as an autodidact, but I know I m missing out on the education one gets from working with and having code reviewed by more senior devs. ...

NSArray s, Primitive types and Boxing Oh My!

I m pretty new to the Objective-C world and I have a long history with .net/C# so naturally I m inclined to use my C# wits. Now here s the question: I feel really inclined to create some type of ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

How to Use Ghostscript DLL to convert PDF to PDF/A

How to user GhostScript DLL to convert PDF to PDF/A. I know I kind of have to call the exported function of gsdll32.dll whose name is gsapi_init_with_args, but how do i pass the right arguments? BTW, ...

Linqy no matchy

Maybe it s something I m doing wrong. I m just learning Linq because I m bored. And so far so good. I made a little program and it basically just outputs all matches (foreach) into a label control. ...

热门标签