哪种是泛型类派生约束的首选语法?

时间:2014-02-25 21:22:50

标签: c# .net generics

记录的派生约束使用where T :子句,我正在修改的示例代码是

public class TwoThingsIPC<T> where T : IPassClass
{ ...
}

其中IPassClass是一个接口。

我使用的第三方代码的格式为

public class TwoThingsIPC<IPassClass>
{ ...
}

两者都会在我的代码中产生相同的行为,但它们是否相同,如果没有,有什么区别?

5 个答案:

答案 0 :(得分:9)

他们不一样。第二个声明具有误导性:

public class TwoThingsIPC<IPassClass>
{ ...
}

将类型约束到IPassClass接口。它对泛型参数使用了较差的名称选择。没有什么可以阻止您创建TwoThingsIPC<int>的实例 - 类的代码中的IPassClass引用只会被int“替换”。 1

另一方面,TwoThingsIPC<IPassClass>类型的变量,例如:

TwoThingsIPC<IPassClass> myVar = new TwoThingsIPC<IPassClass>();

将类型约束到IPassClass接口。


1 这不是真正发生的事情,但我还没有更好的解释。

答案 1 :(得分:2)

你的例子是错的。标识符是标识符,TIPassClass都只是标识符。名字中有什么?所以:

public class TwoThingsIPC<IPassClass>

与:

真的相同
public class TwoThingsIPC<T>

除了在第一种情况下,您使用 真的 令人困惑的名称来表示您在那里声明的类型参数。

也许你在想另一种情况,你会发现自己在选择:

public class AnotherClass : TwoThingsIPC<IPassClass>

public class AnotherClass<TPass> : TwoThingsIPC<TPass>
    where TPass : IPassClass

在这两种情况下,IPassClass必须是已在其他地方声明的类型。

请注意,其中第一个是非泛型类,它具有泛型类作为其基类。第二个是泛型类(因为TPass声明有它的类型参数),它有一个依赖于它自己的泛型参数的基类。

答案 2 :(得分:1)

在泛型类型定义中,where子句用于指定可用作泛型声明中定义的类型参数的参数的类型的约束。

除了接口约束之外,where子句还可以包含基类约束,该约束声明类型必须具有指定的类作为基类(或者是该类本身)才能用作类型参数那个泛型类型

如果要检查通用列表中的项目以确定它是否有效或将其与其他项目进行比较,则编译器必须保证其所必须调用的运算符或方法将受任何类型的支持可能由客户端代码指定的参数。通过将一个或多个约束应用于泛型类定义来获得此保证。

参考文献:
http://msdn.microsoft.com/en-us/library/bb384067.aspx
http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 3 :(得分:0)

'where'是泛型类型约束。

取自http://msdn.microsoft.com/en-us/library/bb384067.aspx

  

在泛型类型定义中,where子句用于指定   对可用作类型参数的类型的约束   泛型声明中定义的参数。例如,你可以   声明一个泛型类MyGenericClass,这样就是type参数   T实现IComparable接口:

以下是一些例子:

public class TwoThingsIPC<T> where T : IPassClass
{ 
}
public class TestClass
{
}
public class TestClass2 : IPassClass
{
}

var test1 = new TwoThingsIPC<TestClass>(); //this will not compile
var test2 = new TwoThingsIPC<TestClass2>(); //this will compile because it implements IPassClass 

其他例子:

public class TwoThingsIPC<T> where T : class
{
}
public class TestClass
{
}
var test1 = new TwoThingsIPC<int>(); //this will not compile because it is a value type

//these will compile because they are reference types 
var test2 = new TwoThingsIPC<TestClass>(); 
var test3 = new TwoThingsIPC<List<TestClass>>(); 

internal delegate void DWork();
var test4 = new TwoThingsIPC<DWork>(); 

<强>参考文献:

http://msdn.microsoft.com/en-us/library/bb384067.aspx

http://msdn.microsoft.com/en-us/library/d5x73970.aspx

答案 4 :(得分:0)

感谢您的帮助;把相关的答复放在一起,并确保我的事实是正确的:

Asawyer 对原帖的评论指出了约束和泛型参数之间的区别......而 D Stanly 说明了如何使用约束为约束的参数要求可以导致草率类型匹配。

Jeppe Stig Nielsen 发现我很快就会想要使用interface参数编写从泛型类继承的类。我问他在哪里可以找到如何做到的例子。

所有人一起坚持支持一些依赖注入...... 再次感谢!