2014-07-25 1 views
3

아래 코드에 문제가 있습니다. 내 방법은 IList가 아닌 목록을 가져오고 싶습니다. 그러나 나는 잘못 알고 있습니까? 여기IList by ref가 메서드 서명 인 경우 참조로 전달 목록

public void DoFoo(ref IList<Foo> thingy) {} 

는 선언과 호출된다 :

var foo = new List<Foo>(); 
DoFoo(ref foo) 

왜이 컴파일되지 않습니다 여기

내 방법? 컴파일러가 List에서 IList로 캐스팅해야하기 때문에 foo가 IList를 구현합니다.

+4

왜 처음에는 거기에 '참조'가 있습니까? –

+0

http://blogs.msdn.com/b/ericlippert/archive/2009/09/21/why-do-ref-and-out-parameters-not-allow-type-variation.aspx를 참조하십시오. 하지만 Lasse가 옳다. 이 코드는 거의 틀린 것입니다. 목록을 전달하려면 list * 유형의 변수에 대한 참조가 아닌 * 목록에 * 참조를 전달하십시오. 전자는'IList '이고, 후자는'ref IList '이다. 그들은 매우 다릅니다. –

+0

이 문제의 정상적인 해결책은 대신'public IList DoFoo (IList thingy) {}'를 사용하고 'IList foo = new List (); foo = DoFoo (foo);'를 사용하는 것입니다. 그래도 추한. – Brian

답변

5

형식 추론이 여기에옵니다. varList을 직접 선언하는 것과 동일하지만 IList이 필요합니다. 선언문에 예상되는 타입을 명시 적으로 작성해야합니다.

IList<foo> foo = new List<Foo>(); 
DoFoo(ref foo) 
+0

또는'var foo = new List () as IList ; ' –

3

가 컴파일되지 않는 이유는 ref이 방법은이 작업을 수행 할 수 있다는 것입니다 :

public void DoFoo(ref IList<Foo> thingy) 
{ 
    thingy = new Foo[10]; 
} 

배열이 IList<T>을 구현,하지만 그들은 List<T>을하지 않은, 컴파일러가 거부 이유입니다 코드를 컴파일하십시오.

특정 유형의 변수 (이 경우 List<Foo>)를 참조하는 매개 변수가 있으며 List<Foo>에서 상속되지 않는 한 다른 유형의 콜렉션을 채울 수 없습니다.

이 딱 맞는 유형의 변수에 목록을 복사,이 문제를 회피하기 방법입니다,하지만 당신은 방법 실제로 그 변수의 내용을 대체하는 경우 발생하는 결정해야합니다.

즉,이 작업을 수행 할 수 있습니다

이미 다른 답변에서 언급
IList<Foo> il = foo; 
DoFoo(ref il); 
// what if il is a new reference here now? 

, 객체 (이 경우에 따라서 목록) 이미 참조입니다. 처음에 ref이 필요합니까? 내가 분명히하자. .NET의 개체는 참조 형식이므로 개체에 대한 참조를 전달합니다. ref 매개 변수를 사용하면 참조 번호으로 매개 변수를 전달할 수 있습니다.

참조를 전달하면 메서드가 외부 세계와 동일한 객체에 액세스 할 수 있습니다. 참조로 전달하면 메서드가 외부에서 변수 에 액세스 할 수 있습니다.

+0

다른 대답에서 말한 것처럼, 참조로 전달하고 값으로 참조 유형을 전달하는 것은 동일하지 않습니다. 기본 동작은 값으로 전달하는 것입니다. http://msdn.microsoft.com/en-us/library/s6938f28.aspx – Vache

+0

나는 그것을 알고있다. 그렇기 때문에 나는 묻는 질문에 대답했다. 그러나 나는 또한 '심판'의 목적이 무엇인지 궁금하다. –

+0

내가 알기로 알았지 만, "개체 (따라서이 경우 목록)가 이미 참조로 전달되었습니다"라인 때문에 명확히하고 있습니다. – Vache