2013-06-10 4 views
6

최근에 구현 한 일부 사용자 정의 사용자 정의 컨트롤에 인터페이스를 추가했습니다. 인터페이스는 꽤 기본입니다.제네릭, 인터페이스 및 캐스팅 관련 문제

Public Interface IMyInterface(Of T As WebControl) 
    Function DoSomething() As T 
End Interface 

구현도 매우 기본적인 :

Public Class MyCustomControl 
    Inherits CompositeControl 
    Implements IMyInterface(Of MyCustomControl) 

Public Function DoSomething() As MyCustomControl _ 
    Implements IMyInterface(Of MyCustomControl).DoSomething 
    ' do stuff 

    Return Me 
End Class 

모든이 시점까지 잘 작동이 체인을 지원 한 가지 방법이있다.

Dim myList = New List(Of IMyInterface(Of WebControl)) 

myList.Add(someCustomControl) 

myList.ForEach(Sub(i) i.DoSomething()) 

someCustomControlIMyInterface(Of MyCustomControl) 대신 IMyInterface(Of WebControl) 구현하는 MyCustomControl이다 : 나는 모든 너무처럼 IMyInterface 인터페이스를 구현하는 컨트롤의 컬렉션을 통해 루프를 시도 할 때 문제가 발생한다.

옵션 엄격한에이 '(WebControl의) IMyInterface'에 'MyCustomControl'에서 암시 적으로 변환 할 수 없습니다 : (나는 someCustomControl을 추가하려고 할 경우)

나는 두 번째 줄에이 오류를 얻고있다.

이 오류를 해결할 수있는 방법이 있습니까? 나는 그 일을하는 것에 가깝지만이 점을 넘어서기 위해서는 제네릭에 대해 충분히 모른다.

+0

'Dim myList = 새 목록 (Of WebControl)'과 같이 myList를 선언하려고 시도하는 동안 대신 'Dim myList = 새 목록 (Of Object)'또는 그와 비슷한 것을 사용해보십시오. – Vishal

+0

@Vishal'IMyInterface' 타입을 가지지 않고서도'ForEach' 루프에있는 객체들에 대해'DoSomething()'을 호출 할 수 없다고 생각합니다. – jbabey

+0

미안하지만, 나는 그것을 몰랐다. – Vishal

답변

4

공변량은 VS 2010에 도입 된 언어 기능으로 문제를 해결합니다.

 
Public Interface IMyInterface(Of Out T As WebControl) 
    Function DoSomething() As T 
End Interface 

당신이 Out 키워드를 사용하는 경우, 당신은 공분산을 사용하고 있습니다 : 당신은 유형 T 그것의 앞에 Out 키워드를 가지고 제네릭 등을 정의 할 필요가있다. 기본 유형의 제네릭 대신 더 파생 된 유형의 제네릭을 사용할 수 있습니다. 따라서 귀하의 경우에는 for 루프와 같이 코드가 일반적으로 IMyInterface(Of WebControl)) 일 것으로 예상되는 곳에서 IMyInterface(Of MyCustomControl)) 개체를 허용합니다.

공분산에는 제한이 있습니다. 공변량 유형 T은 함수 반환 값으로 만 사용할 수 있으며 함수 (또는 하위)에 대한 매개 변수로 사용할 수 없습니다. 예를 들어 IMyInterfaceDoSomething 서명이 닮은 경우, 컴파일러는 불평 것 :

은 체인 시나리오를 감안할 때
' Here the type T is used as an input param - compiler error 
Sub DoSomething(ByVal sampleArg As T) 

, 위 제한은 문제가 있다고 생각하지 않습니다.MSDN에서

추가 정보 :

+0

이것은 정확히 내가 찾고있는 것입니다. 고맙습니다. – jbabey

0

당신은 그것을 추가하기 전에 개체를 캐스팅해야합니다

myList.Add(CType(someCustomControl, IMyInterface(Of WebControl))) 

당신은 또한 인터페이스 자체 인터페이스가없는 일반적인하고 "DoWork"메소드의 리턴 타입 제작 재질 - 구글 번역 참고 할 수 있습니다.

Public Interface IMyInterface 
    Function DoSomething() As IMyInterface 
End Interface 

당신이 가지 인터페이스의 힘에서 떨어져 걸리는 인터페이스 정의의 유형을 지정해야

(구현에 대해 알 필요하지 않음).

+0

체인 기능을 손상시키지 않고 작동시킬 수 있기를 원합니다. – jbabey

+0

인터페이스 자체가 체인 기능을 만족시키지 못하면 인터페이스를 다시 디자인하거나 인터페이스를 사용하지 않아야합니다. 또는 동일한 작업을 수행하는'WebControl'의 기본 클래스를 작성할 수도 있습니다. – Jay

1

나는 당신의 기능 DoSomething이 무엇 모르겠지만, 내가 테스트 목적을 위해 거기에 인스턴스의 CssClass를 할당하려고합니다.

Public Interface IMyInterface(Of Out T As WebControl) 
    Function DoSomething() As T 
End Interface 

을 주목 Out T 매개 변수를 다음과 같이

인터페이스를 선언합니다. 테스트 페이지의 PageLoad 이벤트에

Public Class MyCustomControl1 
    Inherits CompositeControl 
    Implements IMyInterface(Of MyCustomControl1) 

    Public Function DoSomething() As MyCustomControl1 Implements IMyInterface(Of MyCustomControl1).DoSomething 
     ' do stuff 
     Me.CssClass = "XXX" 
     Return Me 
    End Function 

End Class 

Public Class MyCustomControl2 
    Inherits CompositeControl 
    Implements IMyInterface(Of MyCustomControl2) 

    Public Function DoSomething() As MyCustomControl2 Implements IMyInterface(Of MyCustomControl2).DoSomething 
     ' do stuff 
     Me.CssClass = "YYY" 
     Return Me 
    End Function 

End Class 

:

Dim someCustomControl As New MyCustomControl1 
Dim someCustomControl2 As New MyCustomControl2 

Dim myList = New List(Of IMyInterface(Of WebControl)) 

myList.Add(someCustomControl) 
myList.Add(someCustomControl2) 

myList.ForEach(Sub(i) Literal1.Text &= i.DoSomething.CssClass & "<br />") 
결과는

이 모두 someCustomControl & someCustomControl2의 CssClass 속성이 각각 설정되어

인터페이스를 구현 2 컨트롤 만들기 값.

이것은 인터페이스 함수 DoSomething이 성공적으로 호출되었고 인스턴스가 변경되었음을 나타냅니다.

+0

'Out'은 제가 누락 된 것입니다. 고맙습니다. – jbabey