Связывание ListBox с целым числом [duplicate]

Исправить исключение NullReferenceException можно с помощью Null-условных операторов в c # 6 и написать меньше кода для обработки нулевых проверок.

Он используется для проверки нуля до выполнения доступа к члену (?. ) или index (? [).

Пример

  var name = p?.Spouse?.FirstName;

эквивалентен:

    if (p != null)
    {
        if (p.Spouse != null)
        {
            name = p.Spouse.FirstName;
        }
    }

В результате имя будет нулевым когда p равно null или когда p.Spouse имеет значение null.

В противном случае имени переменной будет присвоено значение p.Spouse.FirstName.

Для получения дополнительной информации: Операторы с нулевым условием

16
задан Paul Alexander 9 May 2009 в 11:03
поделиться

2 ответа

Связывание обычно не работает с полями. Большинство привязок основаны, в частности, на модели ComponentModel PropertyDescriptor, которая (по умолчанию) работает над свойствами. Это дает возможность уведомлений, проверки и т. Д. (Ни одна из которых не работает с полями).

По другим причинам, по которым я могу пойти, открытые поля - плохая идея. Они должны быть свойствами, фактом. Аналогично, изменчивые структуры - очень плохая идея. Не в последнюю очередь это защищает от непредвиденных потерь данных (обычно связанных с изменчивыми структурами). Это должен быть класс:

[DataContract]
public class StatusInfo
{
    [DataMember] public int Total {get;set;}
    [DataMember] public string Authority {get;set;}
}

Теперь он будет вести себя так, как вы думаете. Если вы хотите, чтобы это была неизменяемая структура, это было бы нормально (но привязка к данным была бы в одностороннем порядке, конечно):

[DataContract]
public struct StatusInfo
{
    [DataMember] public int Total {get;private set;}
    [DataMember] public string Authority {get;private set;}

    public StatusInfo(int total, string authority) : this() {
        Total = total;
        Authority = authority;
    }
}

Однако я бы сначала спросил, почему это структуры в первую очередь. Редактировать структуру на языках .NET очень редко. Имейте в виду, что прокси-сервер WCF «mex» будет создавать его как класс у потребителя в любом случае (если вы не используете совместное использование сборок).


В ответ на ответ «зачем использовать структуру» ответ ( «unknown (google)»):

Если это ответ на мой вопрос, это неправильно во многих отношениях. Во-первых, типы значений как переменные обычно выделяются (сначала) в стеке. Если они попадают в кучу (например, в массиве / списке), нет большой разницы в накладных расходах от класса - небольшой бит заголовка объекта плюс ссылка. Структуры всегда должны быть маленькими. Что-то с несколькими полями будет чрезмерно крупным и будет либо убивать ваш стек, либо просто вызвать медленность из-за блуждания. Кроме того, структуры должны быть неизменными - если вы действительно не знаете, что делаете.

Практически все, что представляет объект, должно быть бескомпромиссным.

Если вы попадаете в базу данных, скорость struct vs class является не-проблемой по сравнению с выходом из процесса и, вероятно, по сети. Даже если это немного медленнее, это ничего не значит по сравнению с тем, что нужно сделать правильно - т.е. рассматривать объекты как объекты.

Как некоторые метрики над объектами 1M:

struct/field: 50ms
class/property: 229ms

на основе следующего (разница в скорости в распределении объектов, а не в поле vs). Так что примерно в 5 раз медленнее, но все же очень, очень быстро. Поскольку это не будет вашим узким местом, преждевременно не оптимизируйте это!

using System;
using System.Collections.Generic;
using System.Diagnostics;
struct MyStruct
{
    public int Id;
    public string Name;
    public DateTime DateOfBirth;
    public string Comment;
}
class MyClass
{
    public int Id { get; set; }
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Comment { get; set; }
}
static class Program
{
    static void Main()
    {
        DateTime dob = DateTime.Today;
        const int SIZE = 1000000;
        Stopwatch watch = Stopwatch.StartNew();
        List<MyStruct> s = new List<MyStruct>(SIZE);
        for (int i = 0; i < SIZE; i++)
        {
            s.Add(new MyStruct { Comment = "abc", DateOfBirth = dob,
                     Id = 123, Name = "def" });
        }
        watch.Stop();
        Console.WriteLine("struct/field: "
                  + watch.ElapsedMilliseconds + "ms");

        watch = Stopwatch.StartNew();
        List<MyClass> c = new List<MyClass>(SIZE);
        for (int i = 0; i < SIZE; i++)
        {
            c.Add(new MyClass { Comment = "abc", DateOfBirth = dob,
                     Id = 123, Name = "def" });
        }
        watch.Stop();
        Console.WriteLine("class/property: "
                   + watch.ElapsedMilliseconds + "ms");
        Console.ReadLine();
    }
}
23
ответ дан Marc Gravell 4 September 2018 в 09:20
поделиться
  • 1
    Как программист на C ++ я считаю, что ваши комментарии выше очень трудно понять. Я также, похоже, прихожу к разным выводам. Например, вы говорите: «Так что примерно в 5 раз медленнее, но все же очень, очень быстро». В то время как я вижу это как «Использование структур в 5 раз быстрее, но все же очень, очень медленно». – Daniel Paull 5 July 2012 в 04:12
  • 2
    @ Даниэль вздыхает, здесь мы снова идем, «C ++ быстрее, чем все, когда-либо, и должен использоваться всегда». (вздох). В широком спектре применений нет заметной разницы, кроме одного, что значительно легче получить право. – Marc Gravell♦ 5 July 2012 в 07:33
  • 3
    Я никогда не говорил, что C ++ быстрее! Заключая такие, вы указали, что у вас есть серьезные предубеждения (или, может быть, неправильные представления). «В широком спектре применений нет заметной разницы, кроме одного, что значительно легче получить право». - поэтому мы согласны, хотя C ++ может быть быстрее, это не важно - однако C ++ упрощает его правильное, и это важно. Или, может быть, я просто неправильно истолковал то, что вы сказали, чтобы поддержать мой аргумент ... В самом деле. – Daniel Paull 9 July 2012 в 05:41
  • 4
    @ Даниэль, может быть, я неправильно понял ваш смысл & quot; как программист на C ++ ... но все же очень, очень медленный & quot; – Marc Gravell♦ 9 July 2012 в 06:14
  • 5
    Вероятно, ваш тест производительности слишком короткий, чтобы правильно измерить накладные расходы GC. Попробуйте эту модификацию ваших тестов: pastebin.com/Ajkj0hdm - теперь классы на 12 раз медленнее, потому что 80% времени проводится в GC. Теперь сверните РАЗМЕР до 10M и посмотрите «частные байты»: 200 МБ для структур, взлетев до 1 ГБ для классов. – Roman Starkov 23 August 2012 в 11:09

Я могу только догадываться, почему они поддерживают только свойства: возможно, потому, что, как представляется, универсальное соглашение в платформе .NET никогда не выставляет изменчивые поля (, вероятно, для защиты бинарной совместимости ), и они каким-то образом ожидал, что все программисты будут следовать одному и тому же соглашению.

Кроме того, хотя поля и свойства доступны с одним и тем же синтаксисом, привязка данных использует отражение, и (поэтому я слышал) отражение должно использоваться по-разному для полей доступа чем для доступа к свойствам.

0
ответ дан Qwertie 4 September 2018 в 09:20
поделиться
Другие вопросы по тегам:

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