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 3614658
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 18, 20262026-05-18T22:16:36+00:00 2026-05-18T22:16:36+00:00

The C# spec states that an argument type cannot be both covariant and contravariant

  • 0

The C# spec states that an argument type cannot be both covariant and contravariant at the same time.

This is apparent when creating a covariant or contravariant interface you decorate your type parameters with “out” or “in” respectively. There is not option that allows both at the same time (“outin”).

Is this limitation simply a language specific constraint or are there deeper, more fundamental reasons based in category theory that would make you not want your type to be both covariant and contravariant?

Edit:

My understanding was that arrays were actually both covariant and contravariant.

public class Pet{}
public class Cat : Pet{}
public class Siamese : Cat{}
Cat[] cats = new Cat[10];
Pet[] pets = new Pet[10];
Siamese[] siameseCats = new Siamese[10];

//Cat array is covariant
pets = cats; 
//Cat array is also contravariant since it accepts conversions from wider types
cats = siameseCats; 
  • 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-18T22:16:37+00:00Added an answer on May 18, 2026 at 10:16 pm

    As others have said, it is logically inconsistent for a generic type to be both covariant and contravariant. There are some excellent answers here so far, but let me add two more.

    First off, read my article on the subject of variance “validity”:

    http://blogs.msdn.com/b/ericlippert/archive/2009/12/03/exact-rules-for-variance-validity.aspx

    By definition, if a type is “covariantly valid” then it is not usable in a contravariant way. If it is “contravariantly valid” then it is not usable in a covariant way. Something that is both covariantly valid and contravariantly valid is not usable in either a covariant or contravariant way. That is, it is invariant. So, there is the union of covariant and contravariant: their union is invariant.

    Second, let’s suppose for a moment that you got your wish and that there was a type annotation that worked the way I think you want:

    interface IBurger<in and out T> {}
    

    Suppose you have an IBurger<string>. Because it is covariant, that is convertible to IBurger<object>. Because it is contravariant, that is in turn convertible to IBurger<Exception>, even though “string” and “Exception” have nothing whatsoever in common. Basically “in and out” means that IBurger<T1> is convertible to any type IBurger<T2> for any two reference types T1 and T2. How is that useful? What would you do with such a feature? Suppose you have an IBurger<Exception>, but the object is actually an IBurger<string>. What could you do with that, that both takes advantage of the fact that the type argument is Exception, and allows that type argument to be a complete lie, because the “real” type argument is an utterly unrelated type?

    To answer your follow-up question: implicit reference type conversions involving arrays are covariant; they are not contravariant. Can you explain why you incorrectly believe them to be contravariant?

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

Sidebar

Related Questions

Paragraph 6.7.3.8 of the C99 spec states If the specification of an array type
The R 5 RS spec states that as part of the requirements for a
I am using jQuery 1.3.2, and I cannot update that version because of spec
I'm trying to digest this statement in the C# spec, which states (§4.2): A
According to the JTA spec: This interface is intended for use by system level
The C# spec states in section 5.5 that reads and writes on certain types
What part of the C++ spec, or the IEEE float spec, states that a
In the XMLHttpRequest Spec it says that: The DONE state has an associated error
I have a spec in my current project that requires us to advise the
We have a config spec that we use for our builds that we encourage

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.