2010-01-29 1 views
9

나는 큰 배열과 관련된 하우스 키핑을 주로 래퍼하는 클래스가 있습니다. ref 매개 변수를 사용하는 함수가 있습니다. 클래스의 인스턴스를 함수에 전달하면 배열을 보내려고합니다.명시 적 형변환을 ref 매개 변수로 전달 (C#)

나는 명백한 캐스트를 고려했다. byte [] ref 매개 변수가있는 함수가 있다고 가정 해 보겠습니다.

public void SomeFunction(ref byte[] someBytes); 

오버로드 된 명시 적 캐스트가있는 클래스가 있습니다.

class SomeClass 
    { 
     byte[] someBytes; 
     public static explicit operator byte[](SomeClass someInstance) 
     { 
      return someInstance.someBytes; 
     } 
    } 

는 지금은 매개 변수

SomeClass someInstance = new SomeClass(); 
    SomeFunction(ref (byte[]) someInstance); 

컴파일러 "는 심판 또는 축소 인수가 할당 변수 여야"불평으로 클래스와 함수를 호출합니다. 컴파일러를 제대로 마사지하지 못했거나 정말로 할 수 없는지 확실하지 않습니다.

이 나는 ​​건물 또는 함수 반환 값을 고려,하지만 당신은 심판에 의해 그 전달할 수 없습니다 (그리고 나는 왜 ... 볼 자신을 교육 후)

내가 배열 공공 필드하게하지 않으려는 것 ,하지만 그것은 컴파일러를 만족시킵니다. 난 그냥와 배열을 참조하는 지역 변수를 만들 수 가정 ,하지만 ... 전에 각 함수 호출 후 코드의 추가 라인의

편집 : 그것은 된 SomeFuncion에 의해 작성되었습니다 협조 할 수 있습니다 제 3 자와 나는 그것을 변경할 수있는 권한이 없다. 더 나쁜 것은, 나는 그들의 매개 변수가 실제로 참조 될 필요가 있다고 생각하지 않는다. ...

답변

9

캐스트는 할당 할 수있는 변수가 아니다. 명시 적 캐스트 연산자의 반환 값을 전달 중입니다.

당신은 심판로 전달하기 전에 제대로 캐스트 값을 보관 유지하는 변수를 만들 수 있습니다 : 그것은 재 할당 할 수있다 someBytes 변수가 지금

SomeClass someInstance = new SomeClass(); 
byte[] someBytes = (byte[])someInstance; 
SomeFunction(ref someBytes); 

하는 것으로. 내부 값 someInstance을 다시 할당하려면 SomeFunction을 호출 한 후 어떤 식 으로든 someInstance.someBytes을 다시 할당해야합니다.

+0

그래서는 실용적인 솔루션이 공공 필드 또는 그의 유일한 목적에 전달하는 일부 지역 변수의 생성을 은폐하는 간단한 방법 어느 것이 밝혀졌습니다. 좀 더 파고 제네릭은 도움이 될 수 있습니다 않았다 , 너무. – ajs410

+0

맞아요, someInstance를 업데이트하는 데 간단한 설정 도구 만 있으면 충분합니다. 또는 SomeFunction이 인수로 취하고 SomeInstance가 구현하고 해당 인터페이스를 통해 논리를 구현하는 인터페이스를 만들 수 있습니다. –

1

그렇게 할 수 없으면 먼저 변수에 객체를 캐스팅 한 결과를 구체화해야합니다. 당신이 무엇을 물어 허용 된 경우

다음 코드를 고려

public void SomeFunction(ref byte[] someBytes) 
{ 
    someBytes = new byte[] { 1, 2, 3 }; 
} 

SomeClass someInstance = new SomeClass(); 
SomeFunction(ref (byte[]) someInstance); 
// uh-oh, what is "someInstance" now? 

왜 인수가 "심판", 당신이 여기에서 해결하기 위해 노력하고 그 어떤 문제를 표시인가?

+0

원래 써드 파티 개발자가 C++ 라이브러리를 .NET으로 이식했기 때문에 인수가 ref로 표시되었습니다. 내가 해결하려고하는 문제는 someBytes를 공개 필드로 만들거나 로컬 변수를 만들지 않고 ref 주위를 춤추는 것입니다. 나는 하우스 키핑 필드가 사라질 것을 알았 기 때문에 "명시 적 캐스트"를 선택했습니다. someInstance가 SomeBunction에 따라 someBytes에 대한 참조를 전달하기를 기대하고있었습니다. 공개 필드를 사용하는 것과 많이 다르지 않지만 명시 적 캐스트를 강요하면 남용을 덜 일으킬 것입니다. – ajs410

+1

"ref"및 "out"매개 변수에는지지 변수가 필요합니다. 실제로는 그럴 수 없기 때문에 이미 알아 낸 변수를 정의해야합니다. 물론 자신의 클래스에서 shim-methods를 만들어서 번역을 수행 할 수 있으며 대신에 그 메소드를 호출하면 캐스트를 수행하고 변수에 저장하고 실제 메소드를 호출 할 수 있습니다. 좋은 해결책이 될 수도 없습니다. –

+0

최종 해결책은 실제로 byte []에 대한 참조의 로컬 복사본을 만들고 해당 로컬 복사본을 참조하는 것입니다. 이것은 기술적으로 ref를 위반하는 것이지만, 제 3 자 프로그래머가 C#의 ref가 C++의 ref와 같다고 생각합니다. 사실이 아닙니다. – ajs410

1

C#에서 ref 매개 변수로 사용할 수있는 값의 범위는 CLR에서 허용하는 값으로 제한됩니다. 이것은 CLI 스펙의 12.4.1.5.2 절과 12.1.6 절에 지정되어 있습니다.1

  • 정적 필드
  • 배열 요소
  • 캐스트 중 어느 맞지 않는 개체의

  • 로컬 현재 방법 변수
  • 회원 필드

    • 인수를 포함 이것들은 따라서 ref 값으로 사용될 수 없습니다. 참조로 전달하기 전에 로컬과 같은 값에 할당해야합니다.

  • +0

    사양을 참조 주셔서 감사합니다! 나는 잠시 동안 C#에 들어 가지 않았습니다. 그래서 언어의 다양한 기능을 충분히 탐구하면서 학문적 인 질문이 많았습니다 ... 물론 많은 것들이 있습니다. – ajs410

    0

    정말 ref 매개 변수를 캐스팅해야합니까? 내 경우에는 이런 식으로 뭔가 잘 작동합니다.

    byte[] someInstance = (byte[])new SomeClass(); 
    SomeFunction(ref someInstance);