2015-12-25 2 views
3

В C#, если я использую структуру, как показано ниже, и сравнивает равенство, значения полей структуры будут сравниваться, и я получаю результат true, если все поля имеют одинаковые поля value.Это поведение по умолчанию.Использование структур вместо классов для простых типов

struct PersonStruct 
{ 
    public PersonStruct(string n,int a) 
    { 
     Name = n;Age = a; 
    } 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 

var p1 = new PersonStruct("Jags", 1); 

var p2 = new PersonStruct("Jags", 1); 

Console.WriteLine(p1.Equals(p2)); //Return True 

В случае класса то же самое вернет значение false, поскольку оно является ссылочным типом.

class PersonClass 
{ 
    public PersonClass(string n, int a) 
    { 
     Name = n; Age = a; 
    } 
    public string Name { get; set; } 
    public int Age { get; set; } 
} 
var pc1 = new PersonClass("Jags", 1); 
var pc2 = new PersonClass("Jags", 1); 

Console.WriteLine(pc1.Equals(pc2));//Returns False 

Я понимаю, что выше concept.My вопрос рассматривает вышеприведенный сценарий это хорошая идея использовать структуры в таких простых случаях вместо класса? Обычно я видел, как люди реализуют классы в таких случаях (например, простые DTO) и делают все лишние вещи для реализации операторов равенства (таких как метод IEquatable и overridden equals).

Является ли мое понимание правильным или я чего-то не хватает?

+0

Реализация равенства по умолчанию 'System.ValueType' использует отражение и относительно неэффективна. Поэтому вы должны реализовать 'IEquatable ' для ваших структур и классов. Еще важнее, чтобы структуры избегали бокса, который произошел бы при вызове 'object.Equals'. – Lee

+2

Вы должны сделать вашу структуру неизменной, [изменчивые структуры злы] (https://blogs.msdn.microsoft.com/ericlippert/2008/05/14/mutating-readonly-structs/). –

ответ

1

Вы должны избегать по умолчанию выполнение равенства для структур. Если ваши структуры содержат ссылочные типы полей (как PersonStruct), то отражение используется для сравнения соответствующих полей для равенства, которое относительно медленное. Вы также должны реализовать IEquatable<T> для своих структур, поскольку вызов метода object.Equals(object) вызовет бокс для структуры источника и аргумента. Этого можно избежать, если вызов может быть разрешен до IEquatable<PersonStruct>.

1

Общая информация об этом в MSDN.

✓ CONSIDER, определяющий структуру вместо класса, если экземпляры типа являются малыми и обычно недолговечными или обычно внедряются в другие объекты.

X ИЗБЕЖАТЬ определения структуры если тип не имеет все следующие характеристики:

  • Это логически представляет собой одно значение, аналогичное примитивных типов (INT, двойной и т.д.).
  • У него размер экземпляра не более 16 байт.
  • Неизменяется.
  • Его не нужно часто вставлять в коробки.

Во всех остальных случаях вы должны определить свои типы как классы.

Похожие:

When do you use a struct instead of a class?

+1

Ну, это одно эмпирическое правило. Есть и другие, и они одинаково заслуживают доверия. См. «Эффективный C# ч.2» Билла Вагнера, п. 18, стр. 104-110! Цитата: _ Документация для .NET рекомендует учитывать размер типа в качестве определяющего фактора. На самом деле гораздо лучшим фактором является использование типа._ – TaW

+0

Я думаю, что ограничение по размеру связано с тем, что структуры передаются по значению, когда они используются в качестве аргументов, и это может вызвать проблемы, когда у вас много вызовов метода. @TaW – dotctor

Смежные вопросы