C# 通过引用传递到C中的第n个元素#

C# 通过引用传递到C中的第n个元素#,c#,arrays,pass-by-reference,C#,Arrays,Pass By Reference,在C语言中,如果我们有一个数组,我们可以通过引用将它传递给函数。我们还可以使用(n-1)的简单加法来传递从数组的n-第个元素开始的引用,如下所示: char *strArr[5]; char *str1 = "I want that!\n"; char *str2 = "I want this!\n"; char *str3 = "I want those!\n"; char *str4 = "I want these!\n"; char *str5 = "I want them!\n"; st

在C语言中,如果我们有一个数组,我们可以通过引用将它传递给函数。我们还可以使用
(n-1)
的简单加法来传递从数组的
n
-第个元素开始的引用,如下所示:

char *strArr[5];
char *str1 = "I want that!\n";
char *str2 = "I want this!\n";
char *str3 = "I want those!\n";
char *str4 = "I want these!\n";
char *str5 = "I want them!\n";
strArr[0] = str1;
strArr[1] = str2;
strArr[2] = str3;
strArr[3] = str4;
strArr[4] = str5;
printPartially(strArr + 1, 4); //we can pass like this to start printing from 2nd element

....

void printPartially(char** strArrPart, char size){
int i;
for (i = 0; i < size; ++i)
    printf(strArrPart[i]);
}
在C#中,我们还可以通过
ref
(或者,
out
)传递对
对象的引用。对象包括数组,数组是整个数组(或者至少,我认为它是这样工作的)。但是我们如何通过引用传递数组的
n
-th元素,使得函数内部只有
string[]
元素比原始
string[]
元素少一个,而不需要创建新数组

我们必须使用不安全的
?我正在寻找一种没有
不安全的解决方案(如果可能的话)

编辑:

我知道我们可以在C#中传递
Array
,而无需
ref
关键字。也许我的问题听起来相当误导,因为在我们谈论数组时提到了
ref
。我把
ref
放在那里的原因是,我应该这样说:
ref
关键字可以用来传递对数组中
n
-th元素的引用,就像C传递对任何
对象的引用一样(不提
n
-th元素或类似的东西)?我为我的问题措辞中出现的任何误解道歉。

安全的方法是传递一个struct

当然,您可以使用不安全的c#传递指向字符的指针,但是您需要担心缓冲区溢出

顺便说一句,C#中的数组(通常)是在堆上分配的,因此正常传递它(不带ref)并不意味着复制数组-它仍然是传递的引用(只是一个新的引用)。

编辑:

安全代码中,您将无法像在C中那样执行此操作

C#数组(即
string[]
)是从抽象类型派生的。 它不仅仅是一个简单的内存块,就像在C中一样

因此,您不能发送其中一个元素的引用并从那里开始迭代


但是有一些解决方案当然会给你同样的味道(不安全):

比如:

  • 正如@Chris提到的,您可以使用
    ArraySegment
  • 由于
    Array
    也是一个
    IEnumerable
    ,您可以使用
    。跳过
    ,并发送返回值。(但这将提供一个
    IEnumerable
    而不是
    数组
    )。但它将允许您进行迭代
  • 等等

    • 你的困惑是很常见的。关键是要认识到“引用类型”和“通过引用传递”(ref-keyboard)是完全独立的。在这种特定情况下,由于字符串[]是引用类型(与所有数组一样),这意味着在传递对象时不会复制该对象,因此始终引用同一对象

      C#代码的修改版本:


      如果该方法应仅从数组中读取,则可以使用linq:

      string[] strings = {"str1", "str2", "str3", ...."str10"};
      print(strings.Skip(1).Take(4).ToArray());
      

      这个问题由来已久,但也许答案对某人有用。 从C#7.2开始,在这种情况下可以使用更多的类型,例如or。
      它们完全允许您在问题中提到的内容(以及更多内容)。


      目前,如果您想使用它们,请记住在项目的.csproj文件中添加
      7.2
      ,以使用C#7.2功能

      ,您只需将数组和起始索引传递给它即可。代码在
      C
      中工作,因为(至少在本例中)数组和指针是可互换的。在
      C#
      中并非如此(不管它是如何在封面下实现的)。你应该像对待其他有序集合一样对待数组。@Rob是的,这是可能的解决方案,先生。你是对的,并不是我没有想到这种可能性(指传递起始索引),而是我在寻找一种替代方法,如果可能的话,就像我们本能地看到数组应该从索引0开始一样(如C示例),我们也可以在C#函数/方法中这样做。似乎是过早的优化?C#为您进行字符串实习以获得文字字符串,所以我认为它已经被优化了。@Rob我的意思是,毕竟C#有
      ref
      关键字
      。我不知道我们还能做些什么,但我可能不知道。@JesseGood“文字字符串的字符串实习”我不知道这样的功能,先生。这是什么?它有什么作用?谢谢你的链接,先生。我来看看。不过,如果您能对它如何与某些代码一起工作给出更多的解释,那将是最好的。@Ian您可以通过查看源代码轻松了解它的工作原理-(代码中也没有任何非琐碎的东西-它与任何人都会做的一样,只显示数组的视图-在将索引重定向到原始数组之前开始和边界检查的偏移量)如果你需要更多的解释-考虑问一个单独的问题。“AlexeiLevenkov感谢你的材料。检查一下。我知道我们可以在C语言中做,而不是<代码> REF 关键字。也许我的问题误导了一些人。也许我会这样说:可以使用< <代码> REF < /Cord>关键字,比如通过引用。与C一样多地传递到数组的第n个元素?@Ian我编辑了我的答案,以纠正我的误解。但他不想传递整个数组,他想传递一个对数组固定位置的引用。这不起作用。你现在不传递对数组中项目的引用,而是将它们复制到一个新数组,因此更改为t他复制不会影响原件。
      string[] strArr = new string[5];
      strArr[0] = "I want that!\n";
      strArr[1] = "I want this!\n";
      strArr[2] = "I want those!\n";
      strArr[3] = "I want these!\n";
      strArr[4] = "I want them!\n";
      printPartially(strArr.Skip(1).Take(4).ToArray());
      
      void printPartially(string[] strArr)
      {
          foreach (string str in strArr)
          {
              Console.WriteLine(str);
          }
      }
      
      string[] strings = {"str1", "str2", "str3", ...."str10"};
      print(strings.Skip(1).Take(4).ToArray());