2009-07-27 3 views
6

나는 각 항목 사이의 동등한 검사를 수행하는 메소드에서 전달하고자하는 Equals 메소드가있는 콜렉션 클래스를 가지고있다.C# generic 제약 조건에서 '수퍼 유형'관계를 지정할 수 있습니까?

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection<T> 
{ 
    //... 

    public bool Equals<U>(Collection<T> other, EqualityComparer<U> eq) where T : U 
    { 
     // code using eq delegate to test equality between 
     // members of this and other collection 
    } 
} 

불행하게도, 컴파일러 ('Collection.Equals()' 'T를 형식 매개 변수를 정의하지 않습니다이 이상 borks : 또한, 나는 대리자 형식은 T 자체뿐만 아니라 T의 슈퍼 클래스에서 작동하도록 허용 할 '). 이러한 유형의 제약/연산을 지정하는 방법이 있습니까?

답변

4

아니요, 그런 제약을 지정할 수 없습니다. (나는 경우에도 그것을 원했다.)

당신하지만 비 제네릭 클래스에서 두 개의 형태 파라미터를 가지는 정적 일반적인 방법을 쓸 수 :

public delegate bool EqualityComparer<T>(T x, T y); 

public class Collection 
{ 
    public static Equals<T, U>(Collection<T> first, 
           Collection<T> second, 
           EqualityComparer<U> comparer) where T : U 
    { 

    } 
} 

당신은 심지어 전화를 걸 수 일반 클래스의 인스턴스 방법은 당신이 좋아하는 경우 :

// Implementing the static method: 
return first.Equals(second, new EqualityComparer<T>(comparer)); 

컬렉션의 인스턴스 메소드는 단지 것 여기서

public bool Equals(Collection<T> other, EqualityComparer<T> eq) 
{ 
    // ... 
} 

에 사용할 수있는 반공 변성을 사용하여 C# 2 이후 대표를 만듭니다.

+0

가능할 수 있습니까? 추측에 의해 두 선언이 전체 프로젝트에 퍼지거나 심지어 지정되지 않을 수도 있기 때문에 어렵지 않을 것입니다. – Dykam

+1

예, 완벽합니다. 유형 매개 변수가 * 하위 클래스 *가되어야한다고 지정할 수 있습니다. 뭔가 다른, 그래서 왜 다른 방법 라운드? (Java는 이것을 허용합니다.'T extends Foo' 대신에'T super Foo'를 사용합니다.) –

+0

아 - 라이더로 쓰고있는 것을 넣으려는 답을 보았습니다. – ShuggyCoUk

0

명시 적으로 type 매개 변수를 상속 된 U 클래스로 지정하려면 generics는 필요하지 않지만 매개 변수의 형식 유형으로 U를 사용하십시오. 그리고 거기에 polimorfism가 시작됩니다! :)

1

Jon이 말한 것처럼 클래스 수준에서 선언 되었기 때문에 제한에서 T를 참조 할 수 없습니다. 당신이 컬렉션의 개인 상태에 액세스하지 않고 방법을 쓸 수있는 경우

(또는 내부 인 상태) 당신은과 같이 다시 작성할 수 있습니다 :

public class Collection<T> 
{ 
    ... 
} 

public static class CollectionExtentions 
{ 
    public static bool Equals<T,U>(
      this Collection<T> first, 
      Collection<T> other, 
      EqualityComparer<U> eq) where T : U 
    { 
      ... // legal to use eq here on the T values with collections 
    } 
} 

을 덧붙여 나는 당신이 당신의 자신보다는 Func<T,T,bool>을 사용하는 것이 좋습니다 명명 된 위임자

+0

이것은 .NET 2에 있으므로 Func을 사용할 수 없습니다. ( – thecoop

+0

Ah - downer : (해당 라이더를 질문에 추가하고 싶을 수도 있습니다. (분명히 확장 메소드의 구문을 사용할 수 없으므로 Jon의 제안 인스턴스 메소드에 의해 사용되는 정적 메소드의 사용이 가장 좋습니다. – ShuggyCoUk