2013-02-10 13 views
4

의 우리가하는 방법이 있다고 가정 해 봅시다 :[]로는 IEnumerable 문자열의 출력 파라미터를 얻기 <string>

IEnumerable<string> result; 

SomeMethod(out result); 

편집 :

public void SomeMethod(out string[] someArray) { // ... } 

이 비슷한 할 수있는 방법이 있나요을 요점은, 내가 바깥 값을 string[]에 바인딩하고 싶지 않다는 것입니다. 메서드 선언이 SomeMethod(out List<string> outputValue)으로 변경 되더라도 코드가 작동되기를 바랍니다.

+0

이러한 변수의 범위에 대한 자세한 코드와 컨텍스트가 필요합니다. – Matt

+0

그들은 같은 범위에 있습니다. 그들이 다른 범위에 있다면 나는 그것을 나타냅니다. 내가 너를 오해 한 경우 정정을 위해 알려줘. – hattenn

답변

5

형식 안정성을 보장 할 수 없기 때문에 out 매개 변수의 형식을 변경할 수 없습니다. 자세한 내용은 Eric Lippert's Blog에 설명되어 있습니다. 결과는 것으로 someMethod하지만 컴파일러에 대한 호출과 같은 범위에없는 경우 분명히 이것은 단지 문제가

IEnumerable<string> result; 

public void Test() 
{ 
    SomeMethod(out result); 
} 

public void SomeMethod(out string[] someArray) 
{ 
    someArray = new string[]; 
    ChangeTheType(); 

    int n = someArray.Length; // BANG!! - someArray is now a List<string> 
} 

public void ChangeTheType() 
{ 
    result = new List<string>(); 
} 

: 여기

가 허용 될 경우 하나의 유형 안전을 깰 수있는 방법 코드 예제 그걸 확인하지 않을거야. 그것은 단지 허용되지 않습니다.

메서드 서명을 public void SomeMethod(out IEnumerable<string> someStrings)으로 변경하십시오. string[]someStringsSomeMethod을 할당하고 나중에 List<string>을 사용하기로 결정한 경우 통화를 제동하지 않고도 할당 할 수 있습니다.

개인적으로 나는 처음에 매개 변수를 피할 것입니다 : public string[] SomeMethod().

+0

감사합니다. 그리고 이것은 호기심에서 디자인 결정보다 더 많은 질문입니다. 내가 실험하는 동안 그걸 생각해 냈어. – hattenn

2

나는 그것이 최선의 방법이 아니다 확신 해요,하지만 당신은 당신을 위해이 일을 다른 방법을 쓸 수 있습니다 :

public class ClassA 
    { 
     private void SomeMethod(out IEnumerable<string> result) 
     { 
      string[] res; 
      SomeMethod(out res); 
      result = res; 
     } 

     public void SomeMethod(out string[] someArray) 
     { 
      someArray = new string[2]; 
     } 

     void Test() 
     { 
      IEnumerable<string> result; 
      SomeMethod(out result); 
     } 
    } 
+0

요점은 나가는 값이'string []'에 바인드되는 것을 원하지 않는다는 것입니다. 그래도 입력 주셔서 감사합니다. – hattenn

2

당신은 할 수 없습니다 그 주위에 방법이 없기를. 그 이유 중 하나는 CLR이 out을 지원하지 않으며 ref 만 지원한다는 것입니다. 따라서 out은 실제로는 C# 컴파일러에서 추가 된 몇 가지 특별한 규칙을 가지고 ref으로 표현됩니다.

그 주변의 간단한 (그리고 분명한) 방법은 별도의 변수를 생성하는 것입니다 : 당신은 도우미 메서드를 만들 수

string[] resultArray; 

SomeMethod(out resultArray); 
IEnumerable<string> result = resultArray; 

가 할을 당신을 위해 캐스팅 :

public delegate void ActionWithOut<T>(out T result); 

public static void ConvertOut<TBase, TDerived>(
    ActionWithOut<TDerived> method, out TBase result) 
    where TDerived : TBase 
{ 
    TDerived derived; 
    method(out derived); 
    result = derived; 
} 

사용법 :

IEnumerable<string> result; 
ConvertOut<IEnumerable<string>, string[]>(SomeMethod, out result); 

그러나 매개 변수의 개수와 t마다 별도의 오버로드 (및 위임 유형)가 필요합니다. 그는 코드가 실제로 훨씬 좋아 보이지 않습니다. 형식 매개 변수가 필요하므로 형식 유추가이 코드에서 작동하지 않는 것 같습니다.