在c#中列出<int>

Pra*_*ant 6 .net c# reference

我无法理解背后的逻辑,List<int>因为它打破了一些基本规则.

List<int> 应该是值类型而不是引用类型.

  1. List<int>ref如果必须在函数调用之间保持其值,则必须通过关键字传递.所以这意味着它正在显示类似于int的值类型行为.
  2. List<int>必须由新的运营商初始化.也List<int>可以为null.这意味着引用类型行为.

可空类型是不同的,因为它不必由新运算符初始化.

我在这看错了吗?

EDITED-

我应该在原始问题中发布代码.但它遵循 -

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            ListTest d = new ListTest();
            d.Test();
        }
    }

    class ListTest
    {
        public void  ModifyIt(List<int> l)
        {
            l = returnList();
        }

        public void Test()
        {
            List<int> listIsARefType = new List<int>();
            ModifyIt(listIsARefType);
            Console.WriteLine(listIsARefType.Count); // should have been 1 but is 0
            Console.ReadKey(true);
        }

        public List<int> returnList()
        {
            List<int> t = new List<int>();
            t.Add(1);
            return t;
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Joe*_*orn 28

列表应该是值类型而不是引用类型.

错误! int是一种值类型. List<int>是一种参考类型.

  • 可怜,老`参考`; 如此误解.:) (5认同)
  • @Prash如果你想改变引用本身(即:将它设置为null或不同的列表),你会这样做.但我通常不会构建代码来实现这一点. (4认同)
  • @Prashant:你不需要.无论谁告诉你,你总是这样做是个白痴.`ref`关键字的作用是允许您将参数设置为另一个`List <int>`.这甚至不像你认为的那样普遍. (3认同)

mat*_*mc3 7

我认为你的第一颗子弹中有一个错误的假设.通用List对象绝对是引用类型(在堆上,而不是堆栈).不确定为什么你认为你必须通过ref.这打印"2"就像它应该:

namespace ConsoleApplication1 {
   class Program {
      static void Main(string[] args) {
         List<int> listIsARefType = new List<int>();
         ModifyIt(listIsARefType);
         ModifyIt(listIsARefType);
         Console.WriteLine(listIsARefType.Count); // 2!
         Console.ReadKey(true);
      }

      static void ModifyIt(List<int> l) {
         l.Add(0);
      }
   }
}
Run Code Online (Sandbox Code Playgroud)


Wil*_*den 6

您需要了解传递引用,传递值按值传递引用之间的区别.

在代码示例你张贴,你传递的引用List<int>的对象的值.这意味着您可以改变引用指向的对象,并且调用代码将看到这些更改.但是,引用本身是按值传递的,因此如果将引用更改为指向另一个对象,则调用代码将不会看到更改.

当您使用ref关键字时,您将通过引用传递引用.这意味着您不仅可以更改引用指向的对象,还可以更改引用本身.

考虑这个例子:

class Program
{
    static void Main()
    {
        int foo = 0;
        DoSomething1(foo);
        Console.WriteLine(foo); // Outputs 0.

        DoSomething1(ref foo);
        Console.WriteLine(foo); // Outputs 1.

        var bar = new List<int>();
        DoSomething2(bar);
        Console.WriteLine(bar.Count); // Outputs 1.

        DoSomething2(ref bar);
        Console.WriteLine(bar.Count); // Outputs 0.
    }

    // Pass by value.
    static void DoSomething1(int number)
    {
        // Can't modify the number!
        number++;
    }

    // Pass by value.
    static void DoSomething1(ref int number)
    {
        // Can modify the number!
        number++;
    }

    // Pass reference by value.
    static void DoSomething2(List<int> list)
    {
        // Can't change the reference, but can mutate the object.
        list.Add(25);
    }

    // Pass reference by reference.
    static void DoSomething2(ref List<int> list)
    {
        // Can change the reference (and mutate the object).
        list = new List<int>();
    }
}
Run Code Online (Sandbox Code Playgroud)