2010-02-22 2 views
1

기존 코드를 읽습니다. 데이터 객체를 정의하기 위해 함께 구조체와 클래스가있는 많은 데이터 객체 파일이 있음을 발견했습니다. 다음과 같이 : 좋은 스타일이라고 생각합니까?클래스 + 구조체는 좋은 코딩 스타일입니까?

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()을 오버라이드해야하고 문자열 작성기를 사용할 때 public toString() 메서드를 추가하는 것은 좋지 않은 스타일이라고 생각합니다. ... AppendFormat()을 사용하는 대신 문자열 연결 ... – OregonGhost

답변

0

필자는이 방법을 이국적인 P/Invoke 시나리오에서만 사용하는 것이 좋을 것입니다.

먼저 구조체는 변경 가능하기 때문에 잘못 설계되었습니다. 자세한 내용은 this question을 참조하십시오.

클래스는 C#에서 구조를 초기화하는 데 결정적인 방법이 없다는 사실을 처리하기 위해 작성된 것처럼 보입니다. 구조체에 기본 생성자를 제공 할 수 없으며 기본값이 아닌 생성자를 호출 할 수 없습니다. 그래서 클래스가 구조를 감싸고 구조가 어떤 상태로 초기화 될 것이라는 보장을줍니다. 그러나 아무런 유효성 검사도 수행하지 않으므로 전혀 가치가 없음을 강력하게 의심합니다.

LaneDataStruct은 P/Invoke (LayoutKind 특성은 힌트 일 수 있음)에 사용되는 구조를 나타내며 특정 값을 가질 수없는 경우에만 "유용합니다". 유효성 검사를 수행하고 필드를 비공개로 만드는 속성을 제공하는 것이 여전히 바람직합니다. 일반적으로 P/Invoke 코드는 사마귀가 생기면 "이 구조체를 생성 한 후이 구조체를 초기화하십시오"와 같은 별도의 레이어에 작성됩니다.

+0

P/Invoke 란 무엇입니까? – 5YrsLaterDBA

+1

P/Invoke는 .NET이 Windows DLL에서 함수를 호출하는 데 사용하는 메커니즘의 이름입니다. – OwenP

0

C#의 구조체는 약간 다른 의미가 있습니다. MSDN says this는 :

구조체의 유형은 점, 사각형 및 색상과 같은 가벼운 물체를 나타내는 에 적합합니다. 지점을 클래스로 표시 할 수도 있지만 일부 시나리오에서는 구조체가 더 효율적입니다. 이 구별이되지 않은 경우에도

(C++)는 별도의 키워드를 사용하여 POD 유형을 구분하는 것이 좋습니다.

3

공개 필드가있는 가변 구조체라는 사실은 처음에는 좋지 않은 스타일입니다.

나는 그것이 사용 된 것을 본 적이 없다고 말할 수는 없으며, 나는 정말로 원하지 않을 것이다.

+4

버스 시스템이나 임베디드 하드웨어와의 낮은 수준의 통신을 위해 변경할 수있는 구조체를 사용합니다. 일반적인 임베디드 헤더 파일 (MarshalAs 및 StructLayout 물건). 나는 당신이 * 클래스를 사용할 수 있다고 생각하지만, 그 점을 보지 못했습니다. 물론 일반적으로 코드에 대해서는 동의하지만, 사용 가능한 영역이 있다고 생각합니다. – OregonGhost

0

구조체를 이런 방식으로, 특히 StructLayout 특성과 함께 사용하는 유일한 이유는 타사 또는 레거시 C DLL에 PInvoke를 수행하는 경우입니다.이 구조체를 마샬링하려면이 구조체를 전달해야합니다. 내가 구조를 보내고받는 패킷과 정확하게 일치하길 원하는 전선을 통해 일종의 직렬 통신 프로토콜을 수행하고있었습니다.

관련 문제