int []是引用类型还是值类型?

dev*_*ium 117 .net c#

我知道int是一个值类型,但什么是值类型的数组?参考类型?价值类型?我想将一个数组传递给一个函数来检查一些东西.我应该只是传递数组,因为它只是传递它的引用,或者我应该将它传递给ref?

Yan*_*ton 193

数组是允许您将多个项目视为单个集合的机制.Microsoft®.NET公共语言运行库(CLR)支持单维数组,多维数组和锯齿状数组(数组数组).所有数组类型都是从System.Array隐式派生的,System.Array本身派生自System.Object.这意味着 所有数组始终 是在托管堆上分配的引用类型,并且应用程序的变量包含对数组的引用,而不是数组本身.

https://msdn.microsoft.com/en-us/library/bb985948.aspx

  • 值类型继承自System.ValueType,它本身继承自System.Object.因为Array派生自System.Object并不意味着它是一个引用类型.使System.Array成为引用类型的原因是它的实例是通过引用复制的.IOW,专注于System.Array是一个类的事实.这就是它成为参考类型的原因. (48认同)
  • <nitpick>我知道文档可能看起来暗示从System.Object派生的System.Array使它成为引用类型.虽然从System.Object派生的任何类型都是引用类型可能不是真的,但此规则的唯一例外是System.ValueType,编译器对此进行了不同的处理.</ nitpick> (6认同)
  • 任何从 System.Object 派生的内容都是引用类型,除非它也从 System.ValueType 派生。@P.Brian.Mackey 仅仅因为类型是类并不意味着它是引用类型,因为在幕后,结构只是从 System.ValueType 派生的类。 (2认同)

Ale*_*ort 29

参考类型与值类型的最简单测试是引用类型可以是null,但值类型不能.

  • ...除了可以为空的可空值类型(您可以将值设置为null,这意味着类型的空值而不是null*引用*)并且仍然是值类型. (44认同)
  • 在尝试了解它们是否是值类型时,从未想过这样做!好点子。 (3认同)

Jos*_*ins 14

数组(甚至像int这样的值类型)是C#中的引用类型.

http://msdn.microsoft.com/en-us/library/aa288453(VS.71).aspx:

在C#中,数组实际上是对象.System.Array是所有数组类型的抽象基类型.


Mar*_*oli 8

测试以验证它是引用类型还是值类型:

// we create a simple array of int
var a1 = new int[]{1,2,3};
// copy the array a1 to a2
var a2 = a1;
// modify the first element of a1
a1[0]=2;
// output the first element of a1 and a2
Console.WriteLine("a1:"+a1[0]); // 2
Console.WriteLine("a2:"+a2[0]); // 2
//**************************
// all the two variable point to the same array
// it's reference type!
//**************************
Run Code Online (Sandbox Code Playgroud)

您可以在线测试: https: //dotnetfiddle.net/UWFP45

  • 创建一个数组并尝试将其分配为 null 会更容易。如果它是值类型,编译将失败。 (2认同)

小智 6

首先,我想告诉您Array是一种引用类型.为什么?我在这里解释一个例子.

例:

int val = 0; // this is a value type ok
int[] val1 = new int[20] // this is a reference type because space required to store 20 integer value that make array allocated on the heap.
Run Code Online (Sandbox Code Playgroud)

引用类型也可以为null,而值类型则不能.

存储在堆栈中的值类型和存储在堆中的引用类型

您可以使用out或ref将数组传递给函数.只有初始化方法不同.

更多..


Vad*_* S. 5

我想补充一下其他答案,虽然 int[] 是引用类型,但随着stackallocC# 中的引入,您可以将堆栈中的数组分配为值类型。这可能会给你带来性能提升,因为将数组放入堆栈可以减少 GC 压力(顺便说一句,一般来说,谈论值类型时,你可能经常听说值类型是在堆栈中分配的;但事实并非总是如此: https: //learn.microsoft .com/en-us/archive/blogs/ericlippert/the-truth-about-value-types):

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc

stackalloc 表达式在堆栈上分配一块内存。在方法执行期间创建的堆栈分配内存块将在该方法返回时自动丢弃。您无法显式释放使用 stackalloc 分配的内存。堆栈分配的内存块不受垃圾回收的影响,并且不必使用固定语句固定。

使用示例stackalloc

    Span<int> numbers = stackalloc int[10];
    for (int ctr = 0; ctr < numbers.Length; ctr++)
        numbers[ctr] = ctr + 1;
    foreach (int i in numbers)
        Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)

使用此技术时不要忘记有限的堆栈内存。链接https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/stackalloc提供了有关如何stackalloc考虑此限制安全使用的必要信息。

此外,这里有一个讨论实际用法的答案stackallocPractical use of `stackalloc` keywords