4

I have a Visual Studio 2008 C# 2.0 CF project where I am implementing a generic interface, IComparison. The IComparison.Compare method may be called on to do any type of comparison that is valid to for the objects specified, so I don't want to put a type constraint on it.

public interface IComparison<EXPECTED_PARAM>
{
    Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned);
}

The implementation, however, can be more specific. In this case, I'd like to say that the parameter given to GreaterThan.Compare can be compared to the EXPECTED_PARAM given in the constructor via System.IComparable.

public class GreaterThan<EXPECTED_PARAM> : IComparison<EXPECTED_PARAM>
{
    private EXPECTED_PARAM expected_;

    public GreaterThan(EXPECTED_PARAM expected)
    {
        expected_ = expected;
    }

    public Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned) 
        where RETURNED_PARAM : IComparable< EXPECTED_PARAM >
    {
        return ((returned == null && expected_ == null) ||
                (returned != null && returned.CompareTo( expected_ ) > 0)) ?
               Result.Fail : Result.Pass;
    }
}

Unfortunately, this gives me the error:

error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly

What do I need to do to get the ability to perform arbitrary comparisons of EXPECTED_PARAM objects with RETURNED_PARAM objects?

Thanks, PaulH

2 Answers 2

2

How about this?

    public interface IComparison<EXPECTED_PARAM, RETURNED_PARAM>
{
    Result Compare(RETURNED_PARAM returned);
}

public class GreaterThan<EXPECTED_PARAM, RETURNED_PARAM> : IComparison<EXPECTED_PARAM, RETURNED_PARAM> where RETURNED_PARAM : IComparable<EXPECTED_PARAM>
{
    private EXPECTED_PARAM expected_;      
    public GreaterThan(EXPECTED_PARAM expected)     
    {         expected_ = expected;     }      

    public Result Compare(RETURNED_PARAM returned)          
    {
        return ((returned == null && expected_ == null) || 
            (returned != null && returned.CompareTo( expected_ ) > 0)) ?                
            Result.Fail : Result.Pass;
    }
} 
Sign up to request clarification or add additional context in comments.

1 Comment

That's probably what I will have to do. The only thing I don't like is that I didn't have to know the RETURNED_PARAM type until Compare was called before. For this, I have to know both types at construction time. Thanks!
0

Your inheritance hierarchy is the problem. GreaterThan inherits from IComparison<EXPECTED_PARAM>, which means you're telling the compiler that it implements Compare<EXPECTED_PARAM>, but you want it to implement Compare<RETURNED_PARAM> instead. You could drop the generic constraint on your interface:

public interface IComparison
{
    Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned)
    where RETURNED_PARAM : IComparable;
}

public class GreaterThan<EXPECTED_PARAM>: IComparison
{
    private EXPECTED_PARAM expected_;

    public GreaterThan(EXPECTED_PARAM expected)
    {
        expected_ = expected;
    }

    public Result Compare<RETURNED_PARAM>(RETURNED_PARAM returned) 
        where RETURNED_PARAM : IComparable
    {
        return ((returned == null && expected_ == null) ||
                (returned != null && returned.CompareTo( expected_ ) > 0)) ?
               Result.Fail : Result.Pass;
    }
}

3 Comments

If I remove the type constraint from the IComparison interface, then I get the error CS0460: Constraints for override and explicit interface implementation methods are inherited from the base method, so they cannot be specified directly. Also, I prefer the generic IComparable<> interfaces to avoid the boxing/unboxing.
@PaulH I just (re-)tested my example code, it compiles. Does yours look different from mine?
Yes, it compiles as posted, but you mentioned dropping the generic constraint from the IComparison.Compare interface. If I eliminate that where RETURNED_PARAM : IComparable, then it does not compile.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.