【发布时间】:2021-10-12 22:06:11
【问题描述】:
代码
类
using System;
using System.Collections.Generic;
// In case you really, really want to know,
// this class is called Ticket in my real code and it's used as a Tambola ticket.
public class Foo
{
public int?[,] Value { get; private set; } = new int?[3 , 9]
public Foo () => Value = InternalGenerate()
public static Foo Generate () => new() { Value = InternalGenerate() };
protected static int?[,] InternalGenerate ()
{
// Generate a random instance of this class.
}
}
用法
class Program
{
static void Main ()
{
Bar( new() );
}
static void Bar ( Foo foo )
{
int width = foo.GetLength(1);
int height = foo.GetLength(0);
int?[] array = foo.Cast<int?>().ToArray(); // convert foo to 1d array.
// get "corners" of foo
int tl = (int) array.First(e => e.HasValue);
int fl = (int) array.Take(width).Last(e => e.HasValue);
int lf = (int) array.Skip(( height - 1 ) * width).First(e => e.HasValue);
int ll = (int) array.Last(e => e.HasValue);
// this code comes from
// stackoverflow.com/questions/68661235/get-corners-of-a-2d-array
}
}
此代码将失败。
问题
我有一个名为Foo 的课程。
它的实际值 应该 是 int? 类型的二维数组 - 但是,当我尝试使用 Foo 的实例作为 int?[,] (查看代码的使用部分)时,它失败了(其中预计)。
那么,我如何才能像使用集合一样使用Foo 的实例,而不必使用{instance of Foo}.Value?
我不确定,但我相信这被称为包装器。
我尝试过的
我尝试从IEnumerable 继承Foo - 但我之前从未创建过自定义集合类型。所以,经过几个小时的阅读教程和盯着 C# 的源代码,我终于求助于这里提出了一个关于堆栈溢出的问题。
但是,正如我所说,我无法实现IEnumerable - 这样做可能仍然是我问题的答案。在这种情况下,请告诉我该怎么做。
这可能是我最长的问题了
【问题讨论】:
-
从现有实现继承要容易得多,而不必自己实现接口。虽然它不是一个真正的多维集合,但您可以尝试:
public class Foo : List<List<int>> -
好吧,您可以添加自己的
GetLength方法和自己的索引器 (docs.microsoft.com/en-us/dotnet/csharp/programming-guide/…) - 很难知道这是否就是您所需要的全部。 -
@MikalSchachtJensen:通过迭代器实现
IEnumerable<T>非常简单;根据我的经验,从List<T>派生通常不是一个好主意。 (例如,它经常暴露你不想要的操作。) -
您使用 Cast 的用例可以使用来自 Value 的非泛型 Enumerator 进行处理。然而,这不是很有效,使用拳击。因此,请让我们相信一个更好更现实的用例。
-
含义:扩展
// do some stuff with array.
标签: c# arrays .net multidimensional-array c#-9.0