是否可以在C#中的方法中定义本地结构?

Con*_*ngo 42 c#

常见的编程最佳实践之一是"将变量定义为尽可能接近它们的位置".

我经常使用结构来创建几乎在某些地方自我记录的代码.但是,C#强迫我在方法之外定义结构.这打破了上述最佳实践 - 它基本上为整个类创建了一个不需要的全局变量类型.

是否可以在方法中定义局部结构,就像局部变量一样,如果没有,你能给我一个窗口,说明C#设计者决定阻止它的原因吗?

用例

我正在将电子表格的一部分转换为C#代码.我想在方法中使用本地结构以有组织的方式存储临时信息,而不必求助于数百个全局范围的单独变量.

更新 - C#7.0可能具有此功能!

截至2016年8月,显然,这将成为C#7.0的一个功能.

所以C#编译团队同意了 - 哇!

小智 25

我认为不允许在方法中定义命名类型.至于为什么,我将不得不推测.如果一种类型不会在外面使用,那么它的存在可能是不合理的.

但是,您可以在方法中定义匿名类型变量.它有点像结构.妥协.

public void SomeMethod ()
{
    var anonymousTypeVar = new { x = 5, y = 10 };
}
Run Code Online (Sandbox Code Playgroud)

  • 此外,匿名类型是类,而不是结构. (9认同)
  • 我可以想到很多情况下你会在一个方法中使用一个结构 - 一个复杂的LINQ查询,例如,你可能不希望一个大的结果集引起GC压力.结构可以是一种优雅的方式. (7认同)
  • 关闭是,但我可以看到是否有人想要优化导致GC压力过大的查询,结构可能是一个有吸引力的替代方案.(我不认为这是OP想要做的事情,只是指出它只是在一个方法中合法使用结构类型.) (4认同)

Gho*_*Man 12

从 C# 7.0 开始,如果您想要具有命名字段的轻量级数据结构,则可以使用值元组。它们不仅可以在方法内部本地使用,还可以在参数、返回、属性、字段等中使用。您可以使用本地函数在某种程度上模拟结构方法。

var book = (id: 65, pageCount: 535);        // Initialization A
(int id, int pageCount) book2 = (44, 100);  // Initialization B
Console.WriteLine($"Book {book.id} has {book.pageCount} pages.");

(int id, int pageCount) = book;  // Deconstruction into variables
Console.WriteLine($"Book {id} has {pageCount} pages.");
Run Code Online (Sandbox Code Playgroud)

book是类型System.ValueTuple<int, int>(通用结构)。


小智 7

这有点晚了,但这是我的列表解决方案 - 使用匿名变量作为方法内部的结构:

var list = new[] { new { sn = "a1", sd = "b1" } }.ToList(); // declaring structure
list.Clear();                                               // clearing dummy element
list.Add(new { sn="a", sd="b"});                            // adding real element
foreach (var leaf in list) if (leaf.sn == "a") break;       // using it
Run Code Online (Sandbox Code Playgroud)

匿名元素(sn和sd)以某种方式只读.


Ste*_*end 6

你可以使用匿名类型做这样的事情.以下MSDN示例:

var v = new { Amount = 108, Message = "Hello" };
Run Code Online (Sandbox Code Playgroud)

要么

var productQuery = 
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}
Run Code Online (Sandbox Code Playgroud)

  • 不幸的是,如果您想在 v 中定义后重新为变量赋值,这将不起作用,这是我在主要问题中的目标。我想我只需要坚持在方法之外定义结构。 (2认同)