为什么修饰符 "in" 对数组不起作用?
Why doesn't the modifier "in" work for arrays?
我写了一些代码来检查关键字“in”(C#)。添加我知道“in”意味着该参数将是只读的。但它适用于参数类型为 int、double 等的函数,但不适用于 int[]、double[] 等
所以,我写了这段代码,但我没有在第 arr1[i] += 1;
行看到错误。太奇妙了。有人可以解释一下为什么吗?
static int summArray(in int[] arr1, in int[] arr2, int length)
{
int summ = 0;
if (arr1.Length >= length && arr2.Length >= length)
{
for (int i = 0; i < length; i++)
{
arr1[i] += 1;
summ += arr1[i];
summ += arr2[i];
}
return summ;
}
throw new ArgumentException("too small array!");
}
不只是数组;对于任何引用类型, in
修饰符可能会以同样的方式让您大吃一惊。如果不是很明显,数组是引用类型,即使它们是值类型的数组。您可以随时修改数组的内容,就像您可以设置 class Person
实例的 .Name
一样。 in
他们的兄弟们只关心给变量引用赋值,而不是改变变量引用的数据内容
I know that "in" means that parameter will be readonly
变量本身是只读的,因为它不能被重新分配以指向其他东西,但这并不意味着变量指向的东西不能被修改
in
是方法参数的三个标记的一部分:in
、ref
、out
它们主要用于向其他开发人员指示该方法将如何处理传递的引用:
out
表示“该方法肯定会为给定的变量引用分配一些东西”(即不要浪费精力编写将提供具有值的变量的代码,因为它将被替换)
ref
表示“该方法可能会将引用的对象替换为另一个”(即注意检查该方法是否会将您精心创建的数据替换为其他数据,并保存您自己对您的数据(如果您不想冒丢失数据的风险)
in
意思是“该方法不能用不同的对象替换参数引用的对象”(即无论如何需要 5 分钟的 CPU 时间来制作完美的对象;它将通过引用传递,但是当方法完成时,您的代码不会发现它被交换为其他东西)
in
与完全不指定任何内容略有不同;没有说明符通过创建对调用方法持有的对象的引用的副本来传递。当提供一个复制引用时,被调用的方法可以将该引用指向另一个对象,但这对调用者没有任何影响;被调用方法修改副本,因此调用方法不会对其引用实际引用的内容进行任何更改。对于通过原始引用传递的变量,存在被调用方法将它换成其他东西的风险,这意味着调用者可能会丢失它已经准备好的数据
//out: caller shouldn't supply a value; LongProcess's efforts are wasted
var x = LongProcess();
SomeOutMethod(out x);
void SomeOutMethod(out object x){
x = somethingelse; //must be done
}
//ref: caller should be careful if supplying a value; LongProcess's efforts may be wasted
var x = LongProcess();
var savedX = x; //preserve my X in case...
SomeRefMethod(ref x); //maybe this will replace x
void SomeRefMethod(ref object x){
x = somethingelse; //may be done
}
//in: caller shouldn;t worry about supplying a value; LongProcess's efforts won't be wasted
var x = LongProcess();
SomeInMethod(in x);
void SomeInMethod(in object x){
x = somethingelse; //cannot be done
}
当然 none 这与修改传递的对象引用的 内容 有任何关系
void ModifyIt(Person p){
p.Name = "John"; //always possible unless Person forbids it
}
void ModifyIt(int[] x){
x[0] = 1; //always possible no matter what
}
in/ref/out
纯粹与 p = new Person...
、x = new int10]
等操作有关。与 p.Name = ...
或 x[0] = ...
完全无关
我写了一些代码来检查关键字“in”(C#)。添加我知道“in”意味着该参数将是只读的。但它适用于参数类型为 int、double 等的函数,但不适用于 int[]、double[] 等
所以,我写了这段代码,但我没有在第 arr1[i] += 1;
行看到错误。太奇妙了。有人可以解释一下为什么吗?
static int summArray(in int[] arr1, in int[] arr2, int length)
{
int summ = 0;
if (arr1.Length >= length && arr2.Length >= length)
{
for (int i = 0; i < length; i++)
{
arr1[i] += 1;
summ += arr1[i];
summ += arr2[i];
}
return summ;
}
throw new ArgumentException("too small array!");
}
不只是数组;对于任何引用类型, in
修饰符可能会以同样的方式让您大吃一惊。如果不是很明显,数组是引用类型,即使它们是值类型的数组。您可以随时修改数组的内容,就像您可以设置 class Person
实例的 .Name
一样。 in
他们的兄弟们只关心给变量引用赋值,而不是改变变量引用的数据内容
I know that "in" means that parameter will be readonly
变量本身是只读的,因为它不能被重新分配以指向其他东西,但这并不意味着变量指向的东西不能被修改
in
是方法参数的三个标记的一部分:in
、ref
、out
它们主要用于向其他开发人员指示该方法将如何处理传递的引用:
out
表示“该方法肯定会为给定的变量引用分配一些东西”(即不要浪费精力编写将提供具有值的变量的代码,因为它将被替换)ref
表示“该方法可能会将引用的对象替换为另一个”(即注意检查该方法是否会将您精心创建的数据替换为其他数据,并保存您自己对您的数据(如果您不想冒丢失数据的风险)in
意思是“该方法不能用不同的对象替换参数引用的对象”(即无论如何需要 5 分钟的 CPU 时间来制作完美的对象;它将通过引用传递,但是当方法完成时,您的代码不会发现它被交换为其他东西)
in
与完全不指定任何内容略有不同;没有说明符通过创建对调用方法持有的对象的引用的副本来传递。当提供一个复制引用时,被调用的方法可以将该引用指向另一个对象,但这对调用者没有任何影响;被调用方法修改副本,因此调用方法不会对其引用实际引用的内容进行任何更改。对于通过原始引用传递的变量,存在被调用方法将它换成其他东西的风险,这意味着调用者可能会丢失它已经准备好的数据
//out: caller shouldn't supply a value; LongProcess's efforts are wasted
var x = LongProcess();
SomeOutMethod(out x);
void SomeOutMethod(out object x){
x = somethingelse; //must be done
}
//ref: caller should be careful if supplying a value; LongProcess's efforts may be wasted
var x = LongProcess();
var savedX = x; //preserve my X in case...
SomeRefMethod(ref x); //maybe this will replace x
void SomeRefMethod(ref object x){
x = somethingelse; //may be done
}
//in: caller shouldn;t worry about supplying a value; LongProcess's efforts won't be wasted
var x = LongProcess();
SomeInMethod(in x);
void SomeInMethod(in object x){
x = somethingelse; //cannot be done
}
当然 none 这与修改传递的对象引用的 内容 有任何关系
void ModifyIt(Person p){
p.Name = "John"; //always possible unless Person forbids it
}
void ModifyIt(int[] x){
x[0] = 1; //always possible no matter what
}
in/ref/out
纯粹与 p = new Person...
、x = new int10]
等操作有关。与 p.Name = ...
或 x[0] = ...