【C#】Tuple(元组)

元组最大的用处就是,不用为了 一些简单的结构或对象而去新建一个类了。

Tuple

Tuple类是在 .NET Framework4.0 中引入的。元组是一种包含不同数据类型的元素序列的数据结构。它可以用于需要数据结构来保存具有属性的对象,但又不想为其创建单独类型的情况。

语法:

Tuple<T1, T2, T3, T4, T5, T6, T7, TRest>

下面的示例创建一个包含三个元素的元组:

Tuple<int, string, string> person = new Tuple <int, string, string>(1, "Steve", "Jobs");

在上面的示例中,我们创建了一个Tuple包含一个人的记录的实例。我们为每个元素指定一种类型,并将值传递给构造函数。指定每个元素的类型很麻烦。C#引入了一个静态帮助器类Tuple,,该类返回Tuple 的实例,而不必指定每个元素的类型,如下所示。

var person = Tuple.Create(1, "Steve", "Jobs");

一个元组最多只能包含八个元素。当您尝试包含八个以上的元素时,它将产生编译器错误。

var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, 8);

访问元组元素

元组元素可以通过 Item < elementnumber > 属性访问,例如 Item1、 Item2、 Item3等,最多可以访问 Item7属性。Item1属性返回第一个元素,Item2返回第二个元素,依此类推。最后一个元素(第8个元素)将使用 Rest 属性返回。

var person = Tuple.Create(1, "Steve", "Jobs");
person.Item1; // 返回 1
person.Item2; // 返回 "Steve"
person.Item3; // 返回 "Jobs"


var numbers = Tuple.Create("One", 2, 3, "Four", 5, "Six", 7, 8);
numbers.Item1; // 返回 "One"
numbers.Item2; // 返回 2
numbers.Item3; // 返回 3
numbers.Item4; // 返回 "Four"
numbers.Item5; // 返回 5
numbers.Item6; // 返回 "Six"
numbers.Item7; // 返回 7
numbers.Rest; // 返回 (8)
numbers.Rest.Item1; // 返回 8

通常,第8个位置用于嵌套元组,您可以使用Rest属性访问该位置。

嵌套元组

如果要在一个元组中包含八个以上的元素,则可以通过嵌套另一个元组对象作为第八个元素来实现。可以使用Rest属性访问最后一个嵌套元组。要访问嵌套元组的元素,请使用Rest.Item1.Item<elelementNumber>属性。

var numbers = Tuple.Create(1, 2, 3, 4, 5, 6, 7, Tuple.Create(8, 9, 10, 11, 12, 13));
numbers.Item1; // 返回 1
numbers.Item7; // 返回 7
numbers.Rest.Item1; //返回(8,9,10,11,12,13)
numbers.Rest.Item1.Item1; //返回 8
numbers.Rest.Item1.Item2; //返回 9

您可以在序列中的任何位置包括嵌套元组对象。但是,建议将嵌套的元组放在序列的末尾,以便可以使用Rest属性访问它。

var numbers = Tuple.Create(1, 2, Tuple.Create(3, 4, 5, 6, 7,  8), 9, 10, 11, 12, 13 );
numbers.Item1; // 返回 1
numbers.Item2; // 返回 2
numbers.Item3; // 返回 (3, 4, 5, 6, 7,  8)
numbers.Item3.Item1; // 返回 3
numbers.Item4; // 返回 9
numbers.Rest.Item1; //返回13

元组作为方法参数

方法可以将元组作为参数。

static void Main(string[] args)
{    var person = Tuple.Create(1, "Steve", "Jobs");
    DisplayTuple(person);
}

static void DisplayTuple(Tuple<int,string,string> person)
{
    Console.WriteLine($"Id = { person.Item1}");
    Console.WriteLine($"First Name = { person.Item2}");
    Console.WriteLine($"Last Name = { person.Item3}");
}

元组作为返回类型

元组可以从方法返回。

static void Main(string[] args)
{    var person = GetPerson();
}
static Tuple<int, string, string> GetPerson() 
{    return Tuple.Create(1, "Bill", "Gates");
}

元组的用法

元组可以在以下情况下使用:

  1. 当您想从一个方法中返回多个值而不使用ref 或 out参数时。
  2. 当您想通过单个参数将多个值传递给方法时。
  3. 当您想暂时保存数据库记录或某些值而不创建单独的类时。。

元组缺点:

  1. Tuple是一个引用类型,而不是一个值类型。它在堆上分配,并可能导致CPU密集型操作。
  2. Tuple被限制为包括八个元素。如果需要存储更多元素,则需要使用嵌套元组。但是,这可能导致歧义。
  3. 可以使用名称模式 Item <elementNumber> 的属性访问Tuple元素,这是不太合理的。

篇外

ValueTuple是C# 7.0的新特性之一,.Net Framework 4.7以上版本可用。

值元组也是一种数据结构,用于表示特定数量和元素序列,但是是和元组类不一样的,主要区别如下:

  • 值元组是结构,是值类型,不是类,而元组(Tuple)是类,引用类型;
  • 值元组元素是可变的,不是只读的,也就是说可以改变值元组中的元素值;
  • 值元组的数据成员是字段不是属性。
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是使用C#编写的二维装箱问题程序,注释已经加上: ```csharp using System; using System.Collections.Generic; using System.Linq; namespace BinPacking { class Program { static void Main(string[] args) { // 测试数据 int binWidth = 6; int binHeight = 4; List<Box> boxes = new List<Box>() { new Box(3, 2), new Box(1, 1), new Box(2, 4), new Box(1, 2), new Box(3, 1) }; // 调用装箱函数 var packedBoxes = PackBoxes(binWidth, binHeight, boxes); // 输出结果 Console.WriteLine($"Bin size: {binWidth} x {binHeight}"); Console.WriteLine($"Total boxes: {boxes.Count}"); Console.WriteLine($"Packed boxes: {packedBoxes.Count}"); Console.WriteLine("Box positions:"); foreach (var box in packedBoxes) { Console.WriteLine($"Box ({box.Width} x {box.Height}): ({box.X}, {box.Y})"); } } // 装箱函数 static List<Box> PackBoxes(int binWidth, int binHeight, List<Box> boxes) { // 对所有箱子按面积从大到小排序 boxes = boxes.OrderByDescending(b => b.Area).ToList(); // 初始化一个空白的矩形,代表装箱空间 Rectangle bin = new Rectangle(0, 0, binWidth, binHeight); // 初始化已放置箱子的列表 List<Box> packedBoxes = new List<Box>(); // 遍历每个箱子 foreach (var box in boxes) { // 尝试将箱子放置在空白矩形中 var packedBox = PackBoxInRectangle(box, bin); // 如果箱子放置成功,则将其加入已放置箱子列表中 if (packedBox != null) { packedBoxes.Add(packedBox); } } return packedBoxes; } // 在给定矩形中放置箱子 static Box PackBoxInRectangle(Box box, Rectangle rect) { // 如果箱子无法放入矩形,则返回空 if (box.Width > rect.Width || box.Height > rect.Height) { return null; } // 将箱子放置在矩形的左上角 Box packedBox = new Box(box.Width, box.Height); packedBox.X = rect.X; packedBox.Y = rect.Y; // 更新矩形,将已放置的箱子所占用的位置从矩形中删除 int newX = rect.X + box.Width; int newY = rect.Y + box.Height; int newWidth = rect.Width - box.Width; int newHeight = rect.Height - box.Height; // 如果剩余空间在水平方向上大于垂直方向,则将剩余空间分成两个矩形,一个在箱子的右侧,一个在箱子的下方 if (newWidth > newHeight) { Rectangle rightRect = new Rectangle(newX, rect.Y, newWidth, box.Height); Rectangle bottomRect = new Rectangle(rect.X, newY, rect.Width, newHeight); // 尝试先将箱子放在右侧矩形中,如果无法放置,则放在下方矩形中 Box rightPackedBox = PackBoxInRectangle(box, rightRect); if (rightPackedBox != null) { return packedBox; } else { Box bottomPackedBox = PackBoxInRectangle(box, bottomRect); if (bottomPackedBox != null) { return packedBox; } } } // 如果剩余空间在垂直方向上大于水平方向,则将剩余空间分成两个矩形,一个在箱子的下方,一个在箱子的右侧 else { Rectangle bottomRect = new Rectangle(rect.X, newY, rect.Width, newHeight); Rectangle rightRect = new Rectangle(newX, rect.Y, newWidth, rect.Height); // 尝试先将箱子放在下方矩形中,如果无法放置,则放在右侧矩形中 Box bottomPackedBox = PackBoxInRectangle(box, bottomRect); if (bottomPackedBox != null) { return packedBox; } else { Box rightPackedBox = PackBoxInRectangle(box, rightRect); if (rightPackedBox != null) { return packedBox; } } } // 如果无法放置箱子,则返回空 return null; } } // 表示一个矩形 class Rectangle { public int X { get; set; } public int Y { get; set; } public int Width { get; set; } public int Height { get; set; } public Rectangle(int x, int y, int width, int height) { X = x; Y = y; Width = width; Height = height; } } // 表示一个箱子 class Box { public int Width { get; set; } public int Height { get; set; } public int X { get; set; } public int Y { get; set; } public int Area { get { return Width * Height; } } public Box(int width, int height) { Width = width; Height = height; } } } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值