2013-07-31 2 views
1

struct byref 및 readonly를 함수에 전달할 수 있습니까? (다만 C++에서 T const&을 같은)struct byref 및 readonly를 C#의 함수에 전달하는 방법은 무엇입니까?

struct A 
{ 
    public int b; 
} 
void func1(ref A a) // I want to make this `a` immutable 
{ 

} 

어떻게 할까?

업데이트 나의 가장 큰 관심사는 통과

(1) 불변 상태 (2) 효율적으로. 두 번째 관심사는 변이 가능한 개체처럼 국가가 간단하고 쉽게 변해야한다는 것입니다.

+0

왜 ref로 전달 하시겠습니까? –

+0

@astander 복사 비용을 절약합니다. – Eonil

+0

이것이 왜 당신의 가장 큰 관심사입니까? 성능/메모리 문제가 있습니까? –

답변

1

현재 저는 이렇게하고 있습니다. 권투의 일종. ImmutableBox<T>의 인스턴스를 유지함으로써

class 
ImmutableBox<T> where T : struct, new() 
{ 
    public readonly T state; 
    ImmutableBox(T state) 
    { 
     this.state = state; 
    } 
} 

struct 
ExampleStateA 
{ 
    public string someField; 
} 

void 
func1(ImmutableBox<ExampleStateA> passImmutableStateWithBox) 
{ 
} 

, 나는 포인터 사본 불변의 개체를 전달할 수 있으며, State 때문에 State가 변경 가능한 편집 여전히 쉽다. 또한 포인터 비교에 대한 동등 비교를 최적화 할 수있는 기회를 얻습니다.

+0

아주 좋은 패턴입니다. [가능한 매개 변수 생성자 등'ToString'로하지만 더 상태지만 노출 된 필드가 없다는 사실 주위를 맴도는 기본 의미와 함께]'{공공 T 값} 그것은'클래스 ExposedValueHolder 을하는 것도 유용합니다. 때로는 값의 의미가 유용 할 때도 있으며, 때로는 변경 불가능한 의미가 유용하며 때로는 변경 가능한 참조 의미가 유용 할 수 있습니다. 프레임 워크에 이러한 유형이 몇 가지 있었으면 좋겠다. 모든 사람이 바퀴를 다시 만들 필요가 없도록했다. – supercat

+0

형식이 'T'로 표시되지 않은 버그가 내 코드에서 수정되었습니다. – Eonil

+0

@supercat 개인적으로, 나는 불변의 상태가 디자인의 주된 선택이어야하고 가변적 인 상태는 로컬 최적화에만 사용해야한다고 생각한다. (물론 * local *의 범위는 다를 수 있습니다 ...)이 패턴은 실제로 내 필요에 맞습니다. – Eonil

0

ref 매개 변수를 불변으로 만드는 방법이 없다고 생각합니다. 대신, 부작용을 피하기 위해 구조체를 처음부터 불변으로 만들어야합니다. 자세한 내용은 여기 읽기 :

Why are mutable structs evil

+0

"불변 구조체"같은 것이 없습니다. 앞에'struct1'와'struct2' 동일한 유형이며, 경우'struct1' 쓰기 가능한 저장 위치는, 성명'struct1 = struct2'은'struct2의 대응 필드 내용을 대체함으로써 struct1' '의 모든 필드를 돌연변이 것 '. struct를 불변으로 만드는 것은 작은 변화를 훨씬 덜 효율적으로 만들지 만, 우연히 수정되지 않도록 인스턴스를 보호하지는 못합니다. "불변"디자인은 단일 통합 값을 나타내는 데는 적합하지만 관련 필드이지만 독립적 인 값 세트를 나타 내기 위해서는 노출 필드 구조체가 훨씬 좋습니다. – supercat

+0

어쨌든 소위 "불변"구조체는 포스터의 명시된 문제를 해결하기 위해 아무 것도하지 않습니다. – supercat

+0

안녕하세요, 제목에 Eric Lippert를 인용 한 Mark Gravel의 게시물이 포함 된 스레드에 대한 링크가 있습니다. 나는 당신이 최상급의 포스터 중 하나와 C# 언어 디자이너 인 tho를 더 잘 알고 있다는 것을 확신합니다. 왜 당신은 그들이 말하는 것을 신경 써야할까요? – Tsabo

0

.NET에서 const ref의 개념이 없습니다 아아있다. 구조체가 작은 경우 값으로 전달해야합니다. 크기가 큰 경우 구조체의 수신자를 수정하지 말고 (이 경우 효율적으로 ref을 전달할 수 있음) 값을 전달하는 비효율을 감수해야합니다.

구조체를 변경 불가능한 것으로 만드는 것은 문제를 해결하는 데 아무 도움이되지 않지만 일부만 수정하려는 경우 효율성을 저하시킵니다. 컴파일러는 읽기 전용 멤버의 pass-by-reference 멤버 호출을 값별로 전달하도록 조용히 변환하여 "const ref"멤버 호출을 위조하려고 시도하기 때문에 기본 struct를 변형하는 struct 메소드를 사용하지 않는 것이 좋습니다. 필드를 드러내는 구조체에 문제가 있습니다.