2011-08-30 4 views
4

이것은 잠시 동안 궁금해 한 내용입니다. 제목 아래에 오류가 포함 된 여러 가지 질문을 탐색했지만이 사례를 설명하는 오류를 찾을 수 없습니다.또 다른 "할당되지 않은 지역 변수 '무엇이든'"질문 사용

이 예에서

먼저보기 :

private void test() { 
    string errorMessage; 
    bool isOK = SomeClassWithBusinessRules.VerifySomeStuff(idOfStuffToVerify, ref errorMessage); 
    if (!isOK) 
     throw new BusinessException(errorMessage ?? "Some error occured."); 
} 

당신은 컴파일러가이 메시지와 함께 불평이 컴파일 할 경우

오류 'ERRORMESSAGE'

을 할당되지 않은 지역 변수의 2 사용

변수 이니셜 라이저를 null으로 변경하면 사라집니다.

이 컴파일 :

private void test() { 
    string errorMessage = null; 
    bool isOK = SomeClassWithBusinessRules.VerifySomeStuff(idOfStuffToVerify, ref errorMessage); 
    if (!isOK) 
     throw new BusinessException(errorMessage ?? "Some error occured."); 
} 

는 왜 우리는 컴파일 에러가 발생합니까?

+0

'(int idOfStuffToVerify, ref ...)'의'int'가 오타라고 생각합니다. 정정하십시오. –

+0

참 ... 수정 됨, 죄송합니다! – Peter

+1

와우 (Wow)는 너무 빨리 그리고 두 명의 최고 인사들에 의해 답변 된 적이 없었습니다 ... 고마워요! – Peter

답변

14

VerifySomeStuff으로 전달하면 ref을 지정하지만 아직 값이 없습니다. VerifySomeStuff은이 시점에서 정의 된 값이없는 값을 읽을 수 있으므로이 방법은 유효하지 않습니다. null 할당은 명확한 할당 요구 사항을 충족시킵니다.

string errorMessage; 
bool isOK = SomeClassWithBusinessRules.VerifySomeStuff(id, out errorMessage); 
if (!isOK) 
    throw new BusinessException(errorMessage ?? "Some error occured."); 

어떤 법적 될 것이다 (그러나 서명을 변경해야하기 때문에, VerifySomeStuff을 변경해야하며 예외를 제외 ( 가 종료하기 전에 매개 변수에 값을 할당 할 필요 지금 : 대안은 out 것 발생)). 표시된 코드에서 오류가없는 경우 nullVerifySomeStuff으로 지정하여 매개 변수에 할당 할 수 있습니다. 물론

는 부울 및 문자열은 다음 을 복제하는 경우가 목적 "이 문제였다", 당신은 또한 사용할 수 있습니다 당신은 ref에 의해 errorMessage을 전달하는

string errorMessage = SomeClassWithBusinessRules.VerifySomeStuff(id); 
bool isOK = errorMessage == null; 
13

ref 인수로 사용 된 변수를 미리 할당해야하기 때문에 컴파일 오류가 발생합니다. 당신이 대신 out 매개 변수를 사용하는 방법을 변경하면 괜찮을거야이 너무 VerifySomeStuff의 변경을 요구하는

bool isOK = SomeClass.VerifySomeStuff(id, out errorMessage); 

주, 그에게 out 매개 변수를 확인합니다. 그런 다음 메서드는 정상적인 반환 경로에 값을 할당해야하므로 메서드가 정상적으로 반환 될 때까지 errorMessage이 확실히 할당됩니다.

각각 10.6.1.2 및 10.6.1.3 세부 사항은 refout 매개 변수를 참조하십시오.

6

. 이것은 in/out 의미론을 가지고 있습니다. 다른 말로하면, 프로토콜은 수신자가 객체가 초기화되지 않았다고 기대할 수 있다는 것입니다.

단순히 out의 의미를 원한다고 생각됩니다.VerifySomeStufferrorMessage의 경우 ref 대신 out으로 변경하고 out을 사용하도록 호출 코드를 변경하십시오.

out을 사용하여 전달할 때 호출 수신자는 개체가 초기화 될 때까지 읽을 수 없습니다. 또한 피 호출자는 반송하기 전에 해당 진술을 수행 할 책임이 있습니다. 당신이 ERRORMESSAGE 매개 변수에 할당하지 않는 한 당신이 부담하는 방법으로 이동 out를 사용하는 경우

5

당신은 또한

SomeClassWithBusinessRules.VerifySomeStuff(int idOfStuffToVerify, 
      out string errorMessage); 

에 방법을 변경하여 '오류'를 해결할 수 있습니다, 그것은 컴파일되지 않습니다.

2

ref 인수를 전달할 때 호출 된 코드에서 수행 할 수있는 작업 중 하나는 ref 인수 변수를 새로운 위치, 즉 참조를 다시 지정하는 것입니다. 이러한 일이 일어나기 위해서는 먼저 변수가 무언가를 가리켜 야하며 따라서 null 일지라도 할당되어야합니다.

2

질문 (컴파일러가 불평하는 이유는 무엇입니까?)은 이미 다른 사람들이 대답했습니다. 그러나 나는 당신이 당신의 디자인을 재고 것을 제안 : errorMessage 이후

bool isOK = SomeClassWithBusinessRules.VerifySomeStuff(idOfStuffToVerify, ref errorMessage); 
if (!isOK) 
    throw new BusinessException(errorMessage ?? "Some error occured."); 
} 

만 오류가 왜 당신은 여분의 반환 값이 필요합니까 발생하면 필요합니까?

string error = SomeClassWithBusinessRules.VerifySomeStuff(idOfStuffToVerify); 
if (error != null) 
    throw new BusinessException(error); 
} 

가 (물론, 당신은 더 이상 경우 "일부 오류가 발생"이없는 그러나 "쓸모없는"오류 메시지를 보여주는 것은 어쨌든 나쁜 방법입니다..)

에서 : 당신은이를 단축 할 수 오류가 예외적 인 상황 경우 사실은 (즉, 일반 제어 흐름의 일부가 아니라 데이터 나 논리 오류를 나타내는 오히려 뭔가 아니다 뭔가), 그것은 VerifySomeStuff 내부 예외 를 이동하는 의미가 있습니다

// no return value 
SomeClassWithBusinessRules.VerifySomeStuff(idOfStuffToVerify); 

class SomeClassWithBusinessRules { 
    void VerifySomeStuff(int id) { 
     ... 
     if (someCondition) 
      throw new BusinessException(error); 
     ... 
    } 
} 
+0

감사합니다. 이것들은 당신이 가지고있는 매우 유효한 논증이며, 나는 정말로 당신이 그들을 적어 놓는 데 시간을내어 주셔서 감사합니다! 메서드에서 나오는 오류가 흐름의 일부이기 때문에이 방법을 사용했습니다. 이것은 UI에서 호출 될 때 사용자에게 메시지를 표시합니다. 배치에서 잘못되면 예외가 발생합니다. 예외는 out/ref 변수보다 훨씬 비쌉니다. 이동 방법과 같았습니다. 제 질문에있는 사례가 생산 코드의 일부가 아니라는 점을 기억하십시오. 오류는 훨씬 분명합니다 :-) – Peter

+0

@ 피터 : 설명해 주셔서 감사합니다. 예, 당신이 쓰는 것은 의미가 있습니다. – Heinzi

+0

@Peter : 간단한 bool 대신 VerifySoemStuff에서 자신 만의 사용자 정의 유형을 반환한다고 생각해 봤습니까? 성공/실패 bool과 실패한 경우의 오류 메시지 및 생각할 수있는 다른 것을 모두 포함하는 클래스를 만들 수 있습니다. 그런 다음 VerifySoemStuff는이 클래스의 인스턴스를 반환합니다. – Polyfun

관련 문제