MVVM ViewModel = & gt; Просмотреть смешение путаницы [duplicate]

, если у вас есть такой массив:

(пользователи - это имя массива)

  Array = & gt;  [0] = & gt;  (массив) 'user' = & gt;  'john' 'age' = & gt;  '23' [1] = & gt;  (массив) 'user' = & gt;  'jane' 'age' = & gt;  '20' [2] = & gt;  (массив) 'user' = & gt;  'john' 'age' = & gt;  '23'  

и вы хотите удалить дубликаты ... then:

  $ serialized = array ();  for ($ i = 0; $ i & lt; sizeof ($ users); $ i ++) {$ test = in_array ($ users ['user'], $ serialized);  if ($ test == false) {$ serialized [] = $ users ['user'];  }}  

может быть решением: P

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;  Полномочия = полномочия;  }}  

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


В ответ на ответ «why use structs» ( «unknown (google)»):

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

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

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

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

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

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

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

  используя System;  используя System.Collections.Generic;  использование System.Diagnostics;  struct MyStruct {public int Id;  public string Name;  public DateTime DateOfBirth;  public string Комментарий;  } class MyClass {public int Id {get;  задавать;  } public string Имя {get;  задавать;  } public DateTime DateOfBirth {get;  задавать;  } public string Комментарий {get;  задавать;  }} static class Program {static void Main () {DateTime dob = DateTime.Today;  const int SIZE = 1000000;  Часы секундомера = секундомер.StartNew ();  Список & л; MyStruct & GT;  s = новый список & lt; MyStruct & gt; (SIZE);  for (int i = 0; i & lt; SIZE; i ++) {s.Add (новый MyStruct {Комментарий = "abc", DateOfBirth = dob, Id = 123, Name = "def"});  } watch.Stop ();  Console.WriteLine ("struct / field:" + watch.ElapsedMilliseconds + "ms");  watch = секундомер.StartNew ();  Список & л; МойКласс & GT;  c = новый список & lt; MyClass & gt; (SIZE);  for (int i = 0; i & lt; SIZE; i ++) {c.Add (новый MyClass {Комментарий = "abc", DateOfBirth = dob, Id = 123, Name = "def"});  } watch.Stop ();  Console.WriteLine ("class / property:" + watch.ElapsedMilliseconds + "ms");  Console.ReadLine ();  }}  
23
ответ дан Marc Gravell 15 August 2018 в 16:36
поделиться
  • 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 15 August 2018 в 16:36
поделиться
Другие вопросы по тегам:

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