Список <интервал> в c#

Я не могу понять логику позади List<int> поскольку это нарушает некоторые основные правила.

List<int> как предполагается, значим тип и не ссылочный тип.

  1. List<int> должен пройтись ref ключевое слово, если его значение должно быть сохранено между вызовами функции. Таким образом, это означает, что отображает поведение типа значения, подобное интервалу.
  2. Но List<int> должен быть инициализирован новым оператором. Также List<int> могло быть пустым также. Это подразумевает поведение ссылочного типа.

nullable тип отличается, поскольку в нем не должен быть инициализирован новым оператором.

Я вижу что-то не так здесь?

ОТРЕДАКТИРОВАННЫЙ -

Я должен был отправить код в самом исходном вопросе. Но это следует здесь -

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;
        }
    }
}
6
задан Will Vousden 8 July 2010 в 23:31
поделиться

8 ответов

Список должен иметь тип значения, а не тип ссылки.

Неправильно! int - это тип значения. List - ссылочный тип.

28
ответ дан 8 December 2019 в 02:09
поделиться

Я думаю, у вас ошибочное предположение в вашем первом пункте. Общий объект 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);
      }
   }
}
7
ответ дан 8 December 2019 в 02:09
поделиться

Необходимо понимать разницу между передачей по ссылке , передачей по значению и передачей ссылки по значению .

В опубликованном вами примере кода вы передаете ссылку объекту List с помощью значения . Это означает, что вы можете изменить объект, на который указывает ссылка, и вызывающий код увидит эти изменения. Однако сама ссылка передается по значению, поэтому, если вы измените ссылку так, чтобы она указывала на другой объект, вызывающий код не увидит изменений.

Когда вы используете ключевое слово 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>();
    }
}
6
ответ дан 8 December 2019 в 02:09
поделиться

List действительно является ссылочным типом. Но элементы, содержащиеся в списке, являются типами значений.

Нулевые типы, однако, реализованы как структуры (struct Nullable, где T : struct) и поэтому являются типами значений. Причина, по которой вы можете просто написать

int? i = 3;

без ключевого слова new, заключается в том, что приведенный выше синтаксис автоматически транслируется компилятором в код, который будет делать следующее:

Nullable<Int32> i = new Nullable<Int32>(3);

Чтобы лучше понять различия между семантикой типов значений и ссылочных типов, я бы рекомендовал вам прочитать статью Джона Скита на эту тему, в которой вы найдете много наглядных примеров кода:

Jon Skeet: Передача параметров в C#

2
ответ дан 8 December 2019 в 02:09
поделиться

В дополнение к ошибочным предположениям, рассмотренным в других ответах, вы говорите:

List должен быть инициализирован оператором new operator... Это подразумевает поведение ссылочного типа.

Нет, в C# оператор new - это просто синтаксис для вызова конструктора типа. Он используется как для ссылочных, так и для определяемых пользователем типов значений (structs).

0
ответ дан 8 December 2019 в 02:09
поделиться

Не думайте об этом как о List думайте об этом так, как было написано List.

List - это общий класс. Это не структура. Это общий класс, который может работать с типами значений и ссылочными типами.

2
ответ дан 8 December 2019 в 02:09
поделиться

List - это ссылочный тип. И его не обязательно передавать как ссылку.

Тип объектов в списке - вроде как тип значения, за исключением того, что объекты типа значения в любом случае могут оказаться boxed (преобразованными в объекты ссылочного типа), так что... вычеркните этот параграф, когда поймете это.

0
ответ дан 8 December 2019 в 02:09
поделиться

A List - это общий ссылочный тип, вы используете его с типом значения int. Но это все еще ссылочный тип.

1
ответ дан 8 December 2019 в 02:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: