2010-02-22 6 views
1

Я читаю существующий код. Я заметил, что существует много файлов объектов данных, которые имеют структуру и класс вместе для определения объекта данных. Как и следующий: вы думаете, что это хороший стиль?Class + Struct - хороший стиль кодирования?

In ONE file: 

[StructLayout(LayoutKind.Sequential, Pack = 1)] 
    public struct LaneDataStruct 
    { 
     public ushort red; 
     public ushort yellow; 
     public ushort green; 
     public ushort blue; 
     public ushort orange; 
    } 

public class LaneData 
    { 
     private LaneDataStruct laneDataStruct; 
    public LaneData(ushort red, ushort yellow, ushort green, ushort blue, ushort orange) 
    { 
     this.laneDataStruct.red = red; 
     this.laneDataStruct.yellow = yellow; 
     this.laneDataStruct.green = green; 
     this.laneDataStruct.blue = blue; 
     this.laneDataStruct.orange = orange; 
    } 

    public LaneData(ushort[] values) 
    { 
     this.laneDataStruct.red = values[0]; 
     this.laneDataStruct.yellow = values[1]; 
     this.laneDataStruct.green = values[2]; 
     this.laneDataStruct.blue = values[3]; 
     this.laneDataStruct.orange = values[4]; 
    } 

    public LaneData(LaneDataStruct laneDataStruct) 
    { 
     this.laneDataStruct = laneDataStruct; 
    } 

    public LaneDataStruct getLaneDataStruct() 
    { 
     return this.laneDataStruct; 
    } 

    public string toString() 
    { 
     StringBuilder stringBuilder = new StringBuilder(); 
     stringBuilder.Append("LaneData.red=" + this.getLaneDataStruct().red + "\n"); 
     stringBuilder.Append("LaneData.yellow=" + this.getLaneDataStruct().yellow + "\n"); 
     stringBuilder.Append("LaneData.green=" + this.getLaneDataStruct().green + "\n"); 
     stringBuilder.Append("LaneData.blue=" + this.getLaneDataStruct().blue + "\n"); 
     stringBuilder.Append("LaneData.orange=" + this.getLaneDataStruct().orange); 

     return stringBuilder.ToString(); 
    } 
} 
+5

Хотя вы не имеете в виду это, я считаю, что это * плохой стиль, чтобы добавить открытый метод toString(), когда вы должны фактически переопределить 'ToString()', а также использовать построитель строк, но затем конкатенирование строк вместо использования 'AppendFormat()' ... – OregonGhost

ответ

0

Я бы назвал это хорошей практикой в ​​экзотическом сценарии P/Invoke, и даже тогда это сомнительно.

Во-первых, структура плохо спроектирована, так как она изменчива. См. this question для получения дополнительной информации.

Класс выглядит так, как будто он был написан для устранения того факта, что в C# нет детерминированного способа инициализации структуры. Вы не можете предоставить struct конструктор по умолчанию, и вы не можете вызвать вызов конструктора, не являющегося стандартом. Таким образом, похоже, что класс обертывает структуру и дает гарантию, что структура будет инициализирована некоторым состоянием. Тем не менее, он не проверяет, поэтому я сильно сомневаюсь, что для него есть какая-то ценность.

Это было бы «полезно», если LaneDataStruct представляет структуру, которая используется для P/Invoke (атрибут LayoutKind - это подсказка, это может быть правдой) и не может иметь определенных значений. Было бы предпочтительнее предоставить ему свойства, которые выполняют проверку и делают поля частными. Обычно код P/Invoke записывается на отдельном уровне, где считается приемлемым иметь бородавки, такие как «обязательно инициализируйте эту структуру после ее создания».

+0

Что такое P/Invoke? – 5YrsLaterDBA

+1

P/Invoke - это имя механизма, используемого .NET для вызова функций в библиотеках Windows. – OwenP

0

Структуры в C# являются типами POD - с немного отличающейся семантикой. MSDN says this:

Тип структура подходит для , представляющий легкие объекты, такие как точка, прямоугольник, и цвет. Хотя в качестве класса можно представить точку , структура более эффективна в некоторых сценариях.

Даже если этого различия не было (C++), рекомендуется отличать типы POD с использованием отдельного ключевого слова.

3

Тот факт, что это изменчивая структура с открытыми полями, - это плохой стиль для начала.

Я не могу сказать, что видел, как он использовался, и я бы не хотел этого.

+4

Я использую изменчивые структуры для низкоуровневой связи с шинными системами или встроенным оборудованием все время, потому что это самый точный перевод из типичных встроенных файлов заголовков (со всеми этими маршалами и StructLayout). Я думаю, вы * можете * использовать классы для этого, но я не вижу смысла. Конечно, для кода, конечно, я согласен с вами, но я думаю, что * есть область, в которой они могут быть использованы. – OregonGhost

0

Единственная причина, по которой я буду использовать Struct таким образом, особенно с атрибутом StructLayout, является то, что я делал PInvoke для сторонней или старой библиотеки DLL, где мне приходилось передавать эту структуру, которая должна быть перемаркирована, или если я делали какой-то протокол последовательной связи по проводу, где я хотел, чтобы моя структура точно соответствовала пакету, который я отправлял/получал.

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