使用“ref”关键字</class>将List <class>作为参数传递给C#

时间:2014-01-08 21:49:30

标签: c# pass-by-reference

朋友!

所以我一直在写一个简单的程序。基本上,我有一个类(3个字符串,1个int,一些方法)。我正在从文本文件初始化此类的对象的值。我正在使用List。 问题是初始化是一个单独的功能。我在这个函数中声明并初始化了List BOTH。但是,我可能需要其他功能,包括“Program.Main”。

我应该制作一个“全球”课程,并制作一个公开列表&lt;班级&gt; ?我决定立即在我的Program.Main函数中声明它。但是,我不确定,List是通过值还是通过引用传递的。我在网上找到了一个页面,建议使用 ref 关键字。现在我有:

public Class FooClass
{...}

class Program
{
    static void Main(string[] args)
    {
      List<FooClass> fooDB = new List<FooClass>;
      initFromFile(ref fooDB);
    }

    private static initFromFile(ref List<FooClass> fooDB)
    {
       using (StreamReader ... )
       {
          while( ... )
          {
             ...
             fooDB.Add(new FooClass(args))
          }
       }
     }//initFromFile

}//Program

我应该继续像这样工作吗?还是有任何重要的建议?也许“参考”根本不是一个好习惯?

TLDR:我应该制作全局列表还是将其作为参考或其他方式传递(建议)。如果通过引用传递,那么我应该使用 ref 关键字还是有另一种方式?

提前致谢,

~~~ hlfrmn

4 个答案:

答案 0 :(得分:8)

你的程序结构的方式很好,除了不需要使用refList<T>引用类型,这意味着传递给函数的实际上是一个引用(C / C ++术语中的“指针”) List<T>个实例。因此,当函数返回时,对方法中列表的任何修改都将可用。

您使用ref的唯一原因是,如果您想将fooDB指向新的实例

private static initFromFile(ref List<FooClass> fooDB)
{

  fooDB = new List<FooClass>; // if the parameter was not passed by reference 
                               // this instance would not be used by the caller.
  using (StreamReader ... ){
  while( ... )
  {
    ...
    fooDB.Add(new FooClass(args))
  }}
}//initFromFile

修改

更仔细地阅读问题的第一部分,似乎fooDB应该是一个初始化的类成员

class Program
{
    private static List<FooClass> fooDB;

    static void Main(string[] args)
    {
      initFromFile();
      foreach(FooClass f in fooDB)
      {
          // do something
      }
    }

    private static initFromFile()
    {
       fooDB = new List<FooClass>();
       using (StreamReader ... )
       {
          while( ... )
          {
             ...
             fooDB.Add(new FooClass(args))
          }
       }
     }//initFromFile

}//Program

答案 1 :(得分:0)

除非您尝试直接在fooDB函数中设置initFromFile的值,否则无需将其作为ref参数传递。请注意,.NET中的类是reference types,因此当您将列表传递给方法时,方法参数引用传入的同一实例(而不是value types)。 ref parameters用于修改传递给方法引用的参数和变量的值。在典型的.NET开发中几乎不需要使用ref参数。

正常传递它,它会起作用:

static void Main(string[] args)
{
    List<FooClass> fooDB = new List<FooClass>;
    initFromFile(fooDB);
}
private static initFromFile(List<FooClass> fooDB)
{
    using (StreamReader ... ) 
    {
        while( ... )
        {
            ...
            fooDB.Add(new FooClass(args))
        }
    }
}

答案 2 :(得分:0)

通用列表为reference types,因此您无需使用ref关键字。如果您在方法列表中进行了更改,则会影响您的实际列表。

答案 3 :(得分:0)

鉴于上面的代码示例,我建议你的initFromFile()方法只返回列表,即

public Class FooClass
{...}
class Program
{static void Main(string[] args)
{
  var fooData = initFromFile();
}

private static List<FooClass> initFromFile()
{
  var fooDB = new List<FooClass>();

  using (StreamReader ... ){
  while( ... )
  {
    ...
    fooDB.Add(new FooClass(args))
  }}

  return fooDB;
}//initFromFile
}//Program