C#泛型:引用类型与值类型

8

在编写我的API时,我遇到了很多关于通用引用类型和通用值类型之间差异的困惑。

这两者之间在约束和功能方面有哪些区别(最重要/最容易忽略)?

class ReferenceGeneric <T> where ???
{

}

and

struct ValueGeneric <T>: where ???
{

}

编辑 #1 为了澄清问题和我的意图:我想知道你可以使用通用引用类型做什么,而不能使用通用值类型(反之亦然)。

编辑 #2 进一步澄清:如果通用类型是引用类型或值类型,则如何约束 T?每种类型约束方式是否有差异?


你的问题非常令人困惑...虽然有答案,但你想要什么呢? - andleer
你说过有时需要进行微调,能给一个例子吗? - Gulzar Nazim
我在编辑中详细阐述了这个问题。 - Sasha
如果您将问题表述为:“在A和B中,您可以如何不同地处理”,那么这个问题会更有趣。 A) class Foo <T> where T:struct { } B) class Foo <T> where T:class { } - ShuggyCoUk
也许吧,但我对其他事情感兴趣——就像上面所说的 :) - Sasha
那么答案是,在这种情况下,<T> 没有任何区别。简单明了 :) - ShuggyCoUk
2个回答

15
请注意,任何声明为结构体的内容都是值类型,而任何声明为类的内容都是引用类型。换句话说,List<int> 仍然是引用类型,如果你有以下代码:
struct Foo<T>
{
    T value;
}

如果 Foo<string> 仍然是值类型。

至于你可以通过泛型类型进行什么操作 - 它们实际上只遵循值类型和引用类型的常规规则;至于您可以对类型为 T 的值执行哪些操作,这取决于 T 是否/如何受到限制。但这并不会因为泛型类型本身是结构体还是类而有所不同。

编辑:Sasha 在评论中提到了 Nullable<T>。我不确定此处指的“例外”是什么 - 除了 Nullable<T> 不满足 "where T : struct" 或 "where T : class" 约束之一。它仍然是一个值类型(这是重点之一)。


Jon,如果结构类型是Nullable,则会出现异常。您能否详细说明一下呢?谢谢。 - Sasha
“任何声明为 class 的东西都是值类型” 有打错字吗? - ShuggyCoUk
Jon:已经修正了你的拼写错误,以避免混淆 :) - configurator

11
作为对Edit2的回应:您可以通过以下方式限制允许引用或值的类型:
引用:
class ReferenceGeneric <T> where T: class
{

}

值:

struct ValueGeneric <T> where T: struct 
{


}

以下内容来自 MSDN 的这个页面: http://msdn.microsoft.com/zh-cn/library/d5x73970.aspx

控制并发访问

在并发访问时,多个线程可以同时尝试访问相同的资源。 如果这些线程不加控制地访问共享资源,可能会导致数据竞争和死锁等问题。

为了避免这些问题,应该使用一些机制对并发访问进行控制。 .NET 中提供了多种机制,包括 Monitor、Mutex、Semaphore 等。

在使用这些机制时,需要注意保证对共享资源访问的互斥性、同步性和正确性等,以确保程序能够正确运行。


你能通过类来限定结构体吗:struct ValueGeneric <T> where T: class {} - Sasha

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接