有没有一种方法可以创建静态只读数组,但是值在构建时计算?

9

有没有一种方法可以使用某些逻辑创建只读值的静态数组?让我尝试解释一下:

我知道可以这样做:

public static readonly int[] myArray = { 1, 2, 3 };

但是是否有可能做到类似这样的事情:
public static readonly int[] myArray2 = 
{
    for (int i = 0; i < 256; i++)
    {
        float[i] = i;
    }
};

修改后的内容: 一个很好的解决方案: 静态构造函数! http://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=VS.100%29.aspx :D


是的,静态构造函数就是我在帖子中展示给你看的;-) - Arnaud F.
问题没有表述清楚。英语不是我的母语,但我理解您要创建一个“只读值数组”,因此其单元格不能被修改,而不是数组实例本身。 - Mario Vernari
6个回答

11
你可以做的是:
public class YourClass
{
    public static readonly int[] myArray2 = null;

    static YourClass()
    {
        myArray2 = new int[256];
        for (int i = 0; i < 256; i++)
        {
            myArray2 [i] = i;
        }        
    }
}

或者:

public static readonly int[] myArray2 = Enumerable.Range(0, 255).ToArray();

1
这在技术上是在运行时而不是在构建时(如所请求的)进行的。然而,这是我会这样做的方式,因为C#缺乏宏系统。 - John Gietzen
我认为这有些过头了。如果你可以在行内或构造函数中确定数组的大小,那么它的内容随时可以设置/更改。 - Mario Vernari
我想创建一个数组,只需要在静态属性中进行一次,如果在运行时完成也没问题。我的表述可能不太准确。我认为这个解决方案(静态类或单例)可以解决我的问题。谢谢。 - Pedro77

2

是的,请试试:

public static readonly IEnumerable<int> myArray = CreateValues();
public static IEnumerable<int> CreateValues()
{
  return new int[] { 1, 2, 3 };
}

2
public static readonly int[] Array = CreateArray();

private static int[] CreateArray()
{
    return new[] { 1, 2, 3, 4, 5 };
}

1
public static readonly int[] myArray2 = ((Func<int[]>)(() => {
    var array = new int[] { 1, 2, 3 };
    return array;
}))();

更加难以阅读!!! JavaScript 没有教你任何东西吗?:-)

(请注意,这只是一个玩笑!它之所以有趣,是因为它展示了 C# 编译器无法自动发现这个 lambda 函数的类型)

在 JavaScript 中,您将编写与此非常相似的内容:

// ILLEGAL IN C#!!! DANGER, WILL ROBINSON!
public static readonly int[] myArray2 = (() => {
    var array = new int[] { 1, 2, 3 };
    return array;
})();

现在我将看一下“工作”的C#方式(哦!太可怕了!)
public static readonly int[] myArray2 = (
    (Func<int[]>) /* <-- The cast to Func<int[]> delegate */ 
    ( 
    /* Start Declaration --> */ 
        () => { var array = new int[] { 1, 2, 3 }; return array;
    } /* <-- End Declaration */ 
    )
    ) 
    (); /* <-- Here we call it! */ 

C# 可以发现委托的类型(这就是 Func<> 的作用)。它也可以发现 Lambda 表达式的类型(这可能是你想要的)。但它无法仅根据 return 语句自动发现 Lambda 表达式的类型。 - John Gietzen
话虽如此,与 Enumerable.Range(0, 256).ToArray() 相比,这很丑陋。 - John Gietzen
是的,当然。我明白。我只是在说这会让维护者们很头疼。 - John Gietzen
@John 我认为它更有趣的地方在于与Javascript符号表示法的比较。JS符号表示法非常常见(例如在jQuery中)。这就像说:在这里你可以这样做,在这里你不能。我第一次尝试将其从JS转换时,浪费了一个小时(几个月前)。 - xanatos

1

"readonly" 应用于数组实例,而不是其内容。因此,您将无法替换原始数组或修改其大小。但是,对于数组的单元格没有限制,可以随时进行修改。


谢谢你提醒我。有什么解决这个问题的技巧吗? - Pedro77
不确定您的目标,但您是否希望填充数组后将其封闭(即没有其他人可以修改任何单元格)?没有提出的解决方案可以实现这一点,那么为什么要求“只读”字段呢? - Mario Vernari

0

实际上关键字readonly的意思是只能在构造方法中赋值/修改变量。

public static readonly int[] values = Enumerable.Range(0, 256).ToArray();

或者甚至

public static readonly IEnumerable<int> values = Enumerable.Range(0, 256).ToArray();

请参阅MSDN


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