2011-01-08 3 views
1

vb.net에서 여러 제약 조건을 충족하는 일반 매개 변수를 처리 할 수있는 함수를 디자인 할 수 있습니다. 예를 들어, Control에서 상속 받고 IList를 구현하는 클래스를 매개 변수로 허용하는 함수를 사용할 수 있습니다. 이 함수는 이러한 객체에 대해 "Control"또는 "IList"메서드를 사용할 수 있으며 객체를 Control 또는 IList를 필요로하는 객체에 전달할 수 있습니다.이 특정 조합은 간단한 예제를 용이하게하기 위해 선택되었으며 특히 유용한 조합].다중 제약 일반 함수 호출이 실제로 어떻게 작동합니까?

 
    Sub CrossThreadAdd(Of T, U As {Control, IList(Of T)})(ByVal TheControl As U, ByVal NewThing As T) 
     If TheControl.InvokeRequired Then 
      TheControl.BeginInvoke(New Action(Of U, T)(AddressOf CrossThreadAdd), TheControl, NewThing) 
     Else 
      TheControl.Add(NewThing) 
     End If 
    End Sub 

이 접근 방식은 컴파일 타임 타입 안전을 제공합니다. 런타임에 실패 할 수있는 캐스트가 필요하지 않습니다. 다른 방법은 인수를 Control 또는 IList로 전달하고 함수를 다른 함수로 캐스트하는 것입니다. 그러나 전달 된 객체가 실제로 두 제약 조건을 모두 충족시키지 않으면 런타임에 실패합니다.

위에서와 같은 제네릭 함수를 사용하면 어떤 상황에서 두 제약 조건을 충족시킬 개체에 IListableControl (Of T)과 같은 새 인터페이스가있는 것이 더 좋을까요? 자신을 반환하는 Control 속성 (컨트롤로 캐스팅)과 어떤 경우에는 자체 ISelf (T) 인터페이스를 사용하는 것이 더 좋을 것입니다. 구현자가 자체를 반환하는 "자체"속성을 제공 할 것으로 예상되는 경우 T로?

다중 제약 제네릭을 사용하면 런타임 형식 변환을 사용하지 않고도 많은 작업을 수행 할 수 있지만 성능 비용이 얼마인지 알 수 없습니다. 런타임시 65,536 가지 일반 유형을 생성하는 간단한 프로그램을 작성했습니다. Foo (Bar of Foo (Of Foo (Of Blah)) ...))))), 그리고 꽤 느려졌 기 때문에 제네릭을 처리하는 데 필요한 시간을 알 수 있습니다 하지 고정,하지만 난 요인이 영향을 미치지 모르는

답변

1

가 정상적인 기능을 통해 일반적인 기능에 없는 런타임 오버 헤드 옆이 있어야합니다 마찬가지로, 제약 조건의 수는 런타임에 전혀 관계가 없습니다.. - 컴파일러에 의해 확인합니다. 물론 다른 일들이 당신이이 기능에 액세스 할 수 반사를 사용할 때 적용됩니다. 이러한 제약 유용 질문에 대해서는

...

개인적으로, 나는 말할 것입니다 : 자주. 인터페이스는 중 하나만 모델해야합니다. 집계 인터페이스 (예 : IListableControl)를 사용하면 나에게 코드 냄새처럼 들리지만 (물론 여러 제약이있는 제네릭이 있다고 가정합니다. 그렇지 않으면 유형 안전을 제공하는 것이 실제로 필요할 수 있습니다).

+0

집계 인터페이스를 사용하지 않고 개체 인스턴스를 필드 나 컬렉션에 저장하여 나중에 다중 제약 일반 함수에 전달할 수 있습니까? 또한 일부 오버 헤드가있을 것이라고 확신합니다. 제네릭에 클래스 제약이 있어도 generic 함수는 매개 변수의 유형에 관계없이 전달 된 유형을 여전히 알고 있습니다 ("U"는 " ListBox "인 반면 TheControl은"FancyRainbowColoredListbox "의 인스턴스 일 수 있습니다. – supercat

+0

@supercat : 물론, 원하는 제약 조건 (예 : 'Of T, U As {Control, Of T)}'이있는 클래스에 컬렉션을 캡슐화 한 다음 내부 클래스에서 해당 유형을 사용해야합니다. 컬렉션 (예 :'List (Of U)'). 그리고 오버 헤드가 있다고 확신하는 이유는 무엇입니까? 모든 유형 테스트는 컴파일시에만 엄격하게 수행됩니다! 형식을 컴파일 할 때 확인할 수 없으면 코드가 컴파일되지 않습니다. –

+0

컬렉션의 모든 항목이 같은 유형이고 컴파일 타임에 유형을 확인할 수 있으면 문제가 없습니다. 그러나 Control과 IList (Of T)를 상속하는 클래스가 두 개 이상 있지만 IList (Of T)를 상속하는 공통 조상이 없다고 가정 해보십시오.그러한 항목을 이중 구속 메소드로 전달할 수 있도록 그러한 콜렉션을 선언 할 수있는 방법이 있습니까? – supercat

관련 문제