为什么ref结构不能用作类型参数?

时间:2018-06-15 07:41:22

标签: c# c#-7.2 ref-struct

C#7.2 introduced db.Clients.aggregate([ { "$match" : { "_id": ObjectId("5a8528ed0290f7eca89e9a5f"), "IsDeleted": false } }, { "$addFields": { "join": { "$reduce": { "input": "$Projects.Forms", "initialValue": [], "in": { "$concatArrays": [ "$$value", "$$this" ] } } } }}, { "$lookup": { "from": "Forms", "localField": "join", "foreignField": "_id", "as": "join" }}, { "$project": { "Name": 1, "Email": 1, "Projects": { "$map": { "input": "$Projects", "in": { "_id": "$$this._id", "Name": "$$this.Name", "Description": "$$this.Description", "Forms": { "$map": { "input": "$$this.Forms", "in": { "$arrayElemAt": [ "$join", { "$indexOfArray": [ "$join._id", "$$this" ] } ] } } }, "IsActive": "$$this.IsActive" } } }, "IsDeleted": 1 }} ]) s。但是,如果{ "_id" : ObjectId("5b0bd79adcbf901ee404d8c0"), "Name" : "Danielle", "Email" : "Janet@test.com", "Projects" : [ { "_id" : ObjectId("5b1e6f3410ef671cf82404be"), "Name" : "test", "Description" : "ttet", "Forms" : [ { "_id" : ObjectId("5b03ff291c70c513bc9dbfa8"), "Name" : "Employee Information", "Description" : "", "IsActive" : true }, { "_id" : ObjectId("5b16238f30491d1c643f7f28"), "Name" : "test form", "Description" : "", "IsActive" : true }, { "_id" : ObjectId("5afc23f3382646009c5210ab"), "Name" : "Android test", "Description" : "", "IsActive" : true } ], "IsActive" : true }, { "_id" : ObjectId("5b03ffc11c70c513bc9dbfb1"), "Name" : "apadei ief", "Description" : "ttasdadet", "Forms" : [ { "_id" : ObjectId("5b03ff291c70c513bc9dbfa8"), "Name" : "Employee Information", "Description" : "", "IsActive" : true }, { "_id" : ObjectId("5b16238f30491d1c643f7f28"), "Name" : "test form", "Description" : "", "IsActive" : true } ], "IsActive" : true } ], "IsDeleted" : false } 这样:

ref struct

我不能将它用作类型参数:

ref struct

我知道ref结构只能存在于堆栈中,而不能存在于堆中。但是,如果使用这种ref结构的泛型方法保证永远不会将它们放在堆上,如上面使用public ref struct Foo { public int Bar; } 包的示例那么会怎样?为什么我不能在这些情况下将它们用作类型参数?

1 个答案:

答案 0 :(得分:3)

一个引用结构不能用作类型参数,因为它们不能逃逸到堆中。没有机制可以告诉编译器方法保证不会滥用引用结构。

从C#7.2开始,您可以在声明中使用ref修饰符 结构类型。引用结构类型的实例分配在 堆栈,并且无法转至托管堆。为确保这一点, 编译器对ref struct类型的使用限制如下:

  • 引用结构不能是数组的元素类型。
  • 引用结构不能是类的字段的声明类型或非引用结构。
  • 引用结构无法实现接口。
  • 不能将ref结构装箱到System.ValueType或System.Object。
  • 引用结构不能是类型参数。
  • lambda表达式或本地函数无法捕获ref struct变量。
  • 不能在异步方法中使用ref struct变量。但是,您可以在同步方法中使用ref struct变量,例如, 在那些返回Task或Task的程序中。
  • ref struct变量不能在迭代器中使用。

More details from Microsoft about ref structs