-
Notifications
You must be signed in to change notification settings - Fork 6k
Add explanation for contravariance behavior with anonymous functions #47707
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Co-authored-by: BillWagner <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
One minor change, and this is ready.
...e/concepts/covariance-contravariance/using-variance-for-func-and-action-generic-delegates.md
Outdated
Show resolved
Hide resolved
The var keyword represents implicit typing, not explicit typing. This correction addresses the terminology issue pointed out in the code review. Co-authored-by: BillWagner <[email protected]>
...e/concepts/covariance-contravariance/using-variance-for-func-and-action-generic-delegates.md
Outdated
Show resolved
Hide resolved
Co-authored-by: BillWagner <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now ready for final review.
@@ -78,7 +78,57 @@ class Program | |||
} | |||
} | |||
``` | |||
|
|||
|
|||
## Contravariance and Anonymous Functions |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
## Contravariance and Anonymous Functions | |
## Contravariance and anonymous functions |
{ | ||
var personReadContact = (Person p) => p.ReadContact(); | ||
|
||
// This works - contravariance allows assignment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This works - contravariance allows assignment | |
// This works - contravariance allows assignment. |
// This works - contravariance allows assignment | ||
Action<Employee> employeeReadContact = personReadContact; | ||
|
||
// This causes a compile error: CS1661 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
// This causes a compile error: CS1661 | |
// This causes a compile error: CS1661. |
This PR addresses a counterintuitive behavior with lambda expressions and delegate contravariance that was causing confusion for C# developers.
The Problem
The existing documentation explained contravariance well for named methods, but didn't cover why this seemingly equivalent code behaves differently:
The Solution
Added a new section "Contravariance and Anonymous Functions" that explains:
(Person p) => p.ReadContact()
should have typeAction<Person>
when being assigned toAction<Employee>
The new documentation includes complete code examples that demonstrate both the problem and the solutions, helping developers understand this subtle but important compiler behavior.
Fixes #31678.
💬 Share your feedback on Copilot coding agent for the chance to win a $200 gift card! Click here to start the survey.
Internal previews