2012-02-17 5 views
4

으로 변환합니다. 기존 응용 프로그램에서 C# 응용 프로그램을 코딩하려고하지만 Delphi에서 개발 한 것처럼 매우 힘들지 만 몇 가지 방법까지 관리했지만 지금은 문제가 발생했습니다 ...Delphi 변종 레코드를 C# struct

델파이 코드는 다음 코드가 포함되어 변형 기록, 즉

type 
    TFruit = record 
    name : string[20]; 
    case isRound : Boolean of // Choose how to map the next section 
     True : 
     (diameter : Single); // Maps to same storage as length 
     False : 
     (length : Single; // Maps to same storage as diameter 
     width : Single); 
    end; 

너무 따라 기록이 구성되어 그 크기 (case 내부 문). 한편 C# 구조체에서 동일한 작업을 수행하려고했지만 아직 성공하지 못했습니다. somemone이 나를 도와 줄 수 있기를 바랍니다. C#에서 구현할 수있는 방법이 있는지 알려주세요. 미리 감사드립니다 ....

답변

5

명시 적 구조체 레이아웃을 사용하여이 Delphi 변형 레코드를 복제 할 수 있습니다. 그러나, 나는 에 할당하여 length에게 할당하는 것이 매우 바람직하지 않으므로 걱정할 필요가 없습니다. 그 반대의 경우도 마찬가지입니다. 그 델파이 레코드 선언은 1990 년대 중반 델파이 코딩 스타일과 같은 것으로 보인다. 현대 델파이 코드는 그런 식으로 쓰여지지 않습니다.

나는 이런 식으로 그것을 할 단지 것 :

struct Fruit 
{ 
    string name; 
    bool isRound; 
    float diameter; // only valid when isRound is true 
    float length; // only valid when isRound is false 
    float width; // only valid when isRound is false 
} 

더 우아한 옵션은 각 구조체 필드의 특성을 가진 클래스가 될 것입니다. 그리고 잘못된 값인 isRound에 액세스 한 경우 3 개의 부동 소수점에 대한 속성 getter 및 setter가 예외를 발생 시켰다고 알립니다.

+0

이 구조체를 사용하여 비 관리 코드를 호출하는 경우 해당 논리가 작동하지 않습니다. – Ani

+1

아니요,하지만 그럴 것 같지는 않습니다. 질문에 그 사실을 언급하지 않았습니다. 이 질문은 델파이 -> C# 포트라고합니다. –

1

아마도이 트릭을 할 것입니까?

이것은 복사하여 붙여 넣기 솔루션이 아니며, Delphi 구조가 선언되고 정렬되는 방식에 따라 오프셋과 데이터 크기를 변경해야 할 수도 있습니다.

[StructLayout(LayoutKind.Explicit)] 
unsafe struct Fruit 
{ 
    [FieldOffset(0)] public fixed char name[20]; 
    [FieldOffset(20)] public bool IsRound; 
    [FieldOffset(21)] public float Diameter; 
    [FieldOffset(21)] public float Length; 
    [FieldOffset(25)] public float Width; 
} 
+1

두 가지 문제가 있습니다. C#'char'는 2 바이트이지만 Delphi 단축 문자는 char 당 1 바이트입니다. 그리고 당신은 정렬을 설명하지 않았습니다. 컴파일러 설정이 영향을 미칠 수 있지만 델파이 레코드는 정렬됩니다. –

+1

이것은 복사하여 붙여 넣기 솔루션이 아니며 순수하게 나타냅니다. 고맙습니다. 감사합니다. – Ani

+0

정렬되지 않은'float's는 꽤 이상합니다. 오히려 Delphi에서와 똑같이 배치해야하는 경우 제대로 정렬해야한다고 말하기보다는 Delphi * 및 *에서 정렬되지 않은 경우에만 C#에서 동일한 레이아웃으로 정렬해야합니다. 다시 변경하십시오. – hvd

1

당신이하려는 일에 따라 다릅니다.

단순히 해당 구조를 만들려고한다면 David Heffernan의 대답을보십시오. 요즘에는 진정으로 같은 것을 표현하지 않으면 두 필드를 서로 위에 매핑하는 것이 타당하지 않습니다. (개별 항목 또는 배열의 동일한 항목을 말하십시오.)

실제로 파일을 공유하려고하는 경우 ananthonline의 답변 라인을 살펴야하지만 충분히 큰 문제는 있습니다. 주석에 넣으십시오 :

유니 코드 문제가있을뿐만 아니라 C#에서 델파이 쇼킹 스트링에 해당 구조가 없으므로 간단히 필드를 매핑 할 수 없습니다.

문자열 [20]은 실제로 바이트, 길이가 1 바이트이고 그 다음 20 문자 분의 데이터로 구성됩니다. 지정된 길이를 초과하는 것에 대한 보장이 없으므로 길이 코드를 존중해야합니다. 가비지를 찾을 가능성이 높습니다. (힌트 : 디스크에 레코드를 쓰는 경우 새로운 데이터를 넣기 전에 필드를 항상 압축하면 디버깅 할 때 디스크의 파일을 훨씬 쉽게 검사 할 수 있습니다.)

따라서 두 필드를 선언해야합니다 코드를 작성하여 양쪽에서 처리하십시오.

어쨌든 그렇게해야만하기 때문에 안전하지 않은 코드의 필요성을 없애기 위해 코드의 나머지 부분을 처리하는 코드를 작성할 것입니다.