在C#中声明固定大小数组的列表

8

我有一个操作像素的函数。我想创建一个包含RGB值的列表,但是当我这样声明它时:

List<int[]> maskPixels = new List<int[3]>();

它给我报错:

变量声明中不能指定数组大小(尝试使用“new”表达式进行初始化)

像这样添加像素:maskPixels.Add(new int[] { Red, Green, Blue });

有没有一种方法可以做到这一点,或者我必须使用new List<int[]>();


4
为什么不使用List<Color>呢? - Paritosh
1
我也建议使用 List<Color>。但是为了提供另一种选择:您是否考虑过 int[,]int[,,](即多维数组;后者对于存储 x、y 和颜色可能很有用)?与锯齿状数组 (int[][]) 或 数组列表 (List<int[]>) 不同,它们始终是矩形/立方体的,即您无法具有不同数量的元素。 - Tim S.
5个回答

8

虽然没有类似的方法,但既然您正在使用RGB值,为什么不使用Color类呢?

List<Color> maskPixels = new List<Color>();

并像这样初始化每个颜色:

Color c = Color.FromArgb(R,G,B); //assuming R,G,B are int values 

如果您的值在0-255的范围内,则这是存储它们最自然的方式。您有预定义的getter和setter,以获取每个颜色组件。


我希望它们在那个范围内。据我所知,没有多少(或者说根本没有)Windows API调用具有大于255的RGB值... - Matthew Watson
当然,我更多的是在考虑一些其他专有的颜色编码用于硬件或者其他我不知道的目的。假设OP在将它们存储到0-255范围之前进行转换。 - Nikola Davidovic
需要OP提供更多的输入,但我想知道他是否会对这些值进行一些数学计算,也许Color并不适合做这个 - 但是,此时谁知道呢,这可能是完美的解决方案。 - Moo-Juice
@Moo-Juice 完全同意,这就是为什么我加了免责声明的原因 :-) - Nikola Davidovic

6

这是不可能的。只需要想一想就知道了。当你有一个通用类型,比如说 List<T>T 是一个类型参数,对于特定的实例化泛型类型,你需要填充类型 T

但是,int[3] 不是一个类型!确切地说,它是 C# 语法中的一个 array-creation-expression

如果你想限制一个类型只能保存三个值,我建议首先使用 Tuple<int, int, int>。但更好的选择是,我推荐一种专门用于表示 RGB 的类型,比如 System.Drawing.Color(使用 Color.FromArgb(int, int, int))或者你自己定义的类型,如果需要的话。我倾向于后者的原因是,并不是所有的 Tuple<int, int, int> 都是 RGB 的有效表示!

我完全忘记了Color类。这就是我要使用的东西。 关于“array-creation-expression”的解释非常好,正是我在寻找的。谢谢! - Thomas

5

我建议为此创建自己的值类型:

public struct Rgb
{
    int R,
    int G,
    int B
}

List<Rgb> list = new List<Rgb>;

你的意思不是 List<Tuple<Rgb, Rgb, Rgb>> 吗? - Arion
5
@Arion,不是的 :) 我(相信)OP想要存储一系列RGB值,而不是一个包含3个RGB值的列表。 - Moo-Juice
由于我不能使用Tuple(.NET 2.0),除了Color类,我认为这是最好的方法。而且我想这也是非颜色值的唯一方法(结构体)。 - Thomas

5
你不能像这样进行数组初始化,而且每个 int[] 在技术上可能是不同的大小。那么换一种不同的数据结构如何?List<Tuple<int, int, int>>
这将允许你在列表中严格地具有三个整数值,并且由于它是一个具有属性的结构,因此可以通过 LINQ 搜索比数组更快。

2
+1 Tuple<T1,T2,T3> 对于固定大小的小数组来说是一个更好的选择。 - Sergey Kalinichenko
жҲ‘еҜ№Tupleе”ҜдёҖзҡ„й—®йўҳжҳҜдҪ йңҖиҰҒдҪҝз”ЁItem1пјҢItem2е’ҢItem3жқҘеј•з”ЁжҲҗе‘ҳпјҢиҝҷдёҚеӨӘжҳ“иҜ»гҖӮ - Moo-Juice
2
请注意,如果您要表示颜色的话,我认为使用“Color”结构会更好! :) - Matthew Watson
1
@Moo-Juice,我能理解你的意思,这也是为什么我给你的答案点了个赞。这种方法完全可行,而且“技术上”更易读。总有不止一种方法可以达到同样的效果。 - Mike Perrenoud
1
当进行添加操作时,可以利用非泛型的Tuple类型上的静态Create方法,即使用:maskPixels.Add(Tuple.Create(Red, Green, Blue));。因为如果每次都要输入<int,int,int>,你会抓狂的。 - Jeppe Stig Nielsen
显示剩余3条评论

-1
 [Flags]
    public enum RGB
    {
        R,
        G,
        B
    }

...

public List<RGB> l = new List<RGB>();
l.Add(RGB.r | RGB.G)

2
这将使得与单个int元素一起工作成为噩梦。 - Moo-Juice
1
在我看来,使用 struct 更加友好。 - Thomas

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