c # свойство с приватным сеттером: почему новый [..class ..] .. {private property initializer = & hellip; } Работа? [Дубликат]

Наряду с принятым ответом, который правильно объяснил проблему, в понимании вашего списка, если вы используете python-2.x, используйте xrange(), который возвращает более эффективный генератор (range() в python 3 выполняет ту же работу ) _ вместо переменной throw n:

[[1]*4 for _ in xrange(3)]      # and in python3 [[1]*4 for _ in range(3)]

Кроме того, в качестве более Pythonic способа вы можете использовать itertools.repeat() для создания объекта итератора повторяющихся элементов:

>>> a=list(repeat(1,4))
[1, 1, 1, 1]
>>> a[0]=5
>>> a
[5, 1, 1, 1]

PS Используя numpy, если вы хотите создать только массив единиц или нулей, вы можете использовать np.ones и np.zeros и / или для использования других чисел np.repeat():

In [1]: import numpy as np

In [2]: 

In [2]: np.ones(4)
Out[2]: array([ 1.,  1.,  1.,  1.])

In [3]: np.ones((4, 2))
Out[3]: 
array([[ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.],
       [ 1.,  1.]])

In [4]: np.zeros((4, 2))
Out[4]: 
array([[ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.],
       [ 0.,  0.]])

In [5]: np.repeat([7], 10)
Out[5]: array([7, 7, 7, 7, 7, 7, 7, 7, 7, 7])

11
задан Jeroen Vannevel 14 May 2014 в 21:30
поделиться

2 ответа

Короткий ответ:

Он работает через инициализатор коллекции , который вызывает Add для добавления элементов

Длинный ответ:

Coding encodingly C # 3.0, объект, который реализует IEnumerable и имеет подходящий метод Add, может быть инициализирован методом Add.

Items имеет public get accessor и Items это List<T>, который реализует IEnumerable и имеет Add. Вот как компилятор видит ваш код

var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());

Обратите внимание, что компилятор не использует информацию, которую List реализует IEnumerable, вот доказательство, никакое исключение не будет выбрано

public sealed class Order
{
    public Order()
    {
        Items = new MyCollection();
    }

    public MyCollection Items { get; private set; }
}

public sealed class OrderItem
{
}

public class MyCollection : IEnumerable
{
    private readonly List<OrderItem> _items = new List<OrderItem>();

    public void Add(OrderItem item)
    {
        _items.Add(item);
    }

    public IEnumerator GetEnumerator()
    {
        throw new NotImplementedException();
    }
}

из спецификации языка C #

Объект коллекции, к которому применяется инициализатор коллекции, должен иметь тип, который реализует System.Collections.IEnumerable или возникает ошибка времени компиляции. Для каждого заданного элемента по порядку инициализатор коллекции вызывает метод Add на целевом объекте с списком выражений инициализатора элемента в виде списка аргументов, применяя нормальное разрешение перегрузки для каждого вызова. Таким образом, объект коллекции должен содержать применимый метод Add для каждого инициализатора элемента.

6
ответ дан GSerjo 20 August 2018 в 22:49
поделиться
  • 1
    Странно, что ему нужно реализовать IEnumerable, поскольку он не используется инициализатором коллекции. – Magnus 14 May 2014 в 21:36
  • 2
    @Magnus: Это было спорное решение в то время. Мы провели широкое исследование типов, которые имеют метод Add, и обнаружили, что существуют две широкие категории: изменчивые классы коллекции и математические классы. Никто не хотел попасть в ситуацию, когда вы могли бы использовать инициализатор коллекции для выполнения математики. Разъясняющая разница заключалась в том, что коллекции, почти все реализованные IEnumerable и математические типы не сделали, поэтому мы выбрали это как наш shibboleth. – Eric Lippert 17 April 2018 в 21:29

Ваше заявление работает, потому что синтаксис инициализации коллекции использует метод Add() для добавления элементов в коллекцию, а не для установки члена в новый экземпляр коллекции. По сути, ваш код эквивалентен:

var order = new Order();
order.Items.Add(new OrderItem());
order.Items.Add(new OrderItem());

Это прекрасно, поскольку вы только когда-либо используете метод getter.

12
ответ дан Justin Niessner 20 August 2018 в 22:49
поделиться
Другие вопросы по тегам:

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