Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 6066601
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 23, 20262026-05-23T09:31:05+00:00 2026-05-23T09:31:05+00:00

On the msdn page on contravariance I find a quite interesting example that shows

  • 0

On the msdn page on contravariance I find a quite interesting example that shows “benefits of contravariance in IComparer”

First they use a fairly odd base & derived classes:

public class Person
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class Employee : Person { }

I can already say that its a bad example cause no class ever just inherits a base class without adding at least a little something of its own.

Then they create a simple IEqualityComparer class

class PersonComparer : IEqualityComparer<Person>
{
    public bool Equals(Person x, Person y)
    {            
        ..
    }
    public int GetHashCode(Person person)
    {
       ..
    }
}

Next the example in question goes.

List<Employee> employees = new List<Employee> {
               new Employee() {FirstName = "Michael", LastName = "Alexander"},
               new Employee() {FirstName = "Jeff", LastName = "Price"}
            };

IEnumerable<Employee> noduplicates = 
employees.Distinct<Employee>(new PersonComparer());

Now my question – first of all in this case Employee is an unneeded class, its true that it can use PersonComparer for this situation because it is in fact just a person class!

In real world however Employee will have at least one new field, lets say a JobTitle. Given that its pretty clear that when we want distint Employees we would need to take that JobTitle field in mind for comparison, and its pretty clear that Contravariant Comparer such as person comparer isn’t suited for that job, cause it cannot know any new members Employee has defined.

Now of course any language feature even a very odd one could have its uses, even if its illogical for some situation, but in this case I think it won’t be useful far too often to be a default behavior. In fact it appears to me as we are breaking type safety a little bit, when a method expects a Employee comparer we can in fact put in a person or even object comparer and it will compile with no problems. While its hard to imagine our default scenario would be to treat Employee like an object..or basic Person.

So is it really a good contravariance for default for those interfaces?

EDIT: I understand what contravariance and covariance is. I am asking why those comparing interfaces were changed to be contravariant on default.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-23T09:31:06+00:00Added an answer on May 23, 2026 at 9:31 am

    This question comes off more as a rant, but let’s back up a moment and talk about the comparer.

    The IEqualityComparer<T> is useful when you need to override whatever default equality comparer is available for the object. It could be using its own equality logic (overriding Equals and GetHashCode), it could be using a default referential equality, whatever. The point is you don’t want whatever its default is. IEqualityComparer<T> allows you to specify precisely what you wish to use for equality. And it lets you define as many different ways as you need to solve your many different problems you might have.

    One of those many different problems might just happen to be solvable by a comparer that already exists for a lesser derived type. That’s all that’s happening here, you have the ability to supply the comparer that solves the problem you need to be solved. You can use the more generic comparer while having a more derived collection.

    In this problem, you’re saying “it’s OK to compare on just the base properties but it’s not OK for me to put a lesser derived object (or sibling) into the collection.”

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

At MSDN page for Stopwatch class I discovered link to interesting article which makes
This MSDN page mentions that there're nothrow versions of new and delete . nothrow
DependencyProperty.AddOwner MSDN page offers an example with two classes with static members, and the
Reading the MSDN page, it is clear that Send will block if there are
When I go to the MSDN page for the SqlConnection class, it only shows
I can compile this code that I got from an MSDN page : using
The MSDN page for byte says that you can declare a byte like this:
According to the last sentence on this MSDN page use is to be preferred
I am pretty much following the example on this MSDN page: http://code.msdn.microsoft.com/Imoprt-Data-from-Excel-to-705ecfcd with 1
I'm using something similar to example C on this MSDN page: http://msdn.microsoft.com/en-us/library/ms190307.aspx DECLARE @tableHTML

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.