VB -> C#: Generic extension method inference widens element types when using a base-type comparer
Maintainers usually reply within 3 days
Nobody has claimed this yet.
Assessment
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Newbie friendliness
- 55/100
Research direction
Start from the VB-to-C# conversion path for generic extension-method calls and reproduce the issue with the VB input in the report. Compare the generated Distinct call with the expected output; done means it specifies DerivedValue and preserves the declared return type.
Written by the indexing model from the issue text.
Description
VB.Net input code
Imports System.Collections.Generic
Imports System.Linq
Public Class BaseValue
Public Property Key As Integer
End Class
Public Class DerivedValue
Inherits BaseValue
End Class
Public Module Helpers
Public Function ToDictionary(values As IEnumerable(Of DerivedValue)) As Dictionary(Of Integer, DerivedValue)
Return values.Distinct(EqualityComparer(Of BaseValue).Default).ToDictionary(Function(value) value.Key)
End Function
End Module
Erroneous output
The converted method leaves the generic arguments of Distinct implicit:
public static Dictionary<int, DerivedValue> ToDictionary(IEnumerable<DerivedValue> values)
{
return values.Distinct(EqualityComparer<BaseValue>.Default).ToDictionary(value => value.Key);
}
C# infers BaseValue as the element type of Distinct, so ToDictionary returns Dictionary<int, BaseValue>.
This produces:
CS0029: Cannot implicitly convert type
'System.Collections.Generic.Dictionary<int, BaseValue>'
to 'System.Collections.Generic.Dictionary<int, DerivedValue>'
Expected output
The converter should preserve the type argument inferred by VB.NET:
public static Dictionary<int, DerivedValue> ToDictionary(IEnumerable<DerivedValue> values)
{
return values.Distinct<DerivedValue>(EqualityComparer<BaseValue>.Default).ToDictionary(value => value.Key);
}
Details
- Product: Visual Studio extension, built locally from master.
- Version: 10.0.1 (local development build).
- Previous working version: No.
VB.NET and C# use different type inference rules for generic extension methods.
VB.NET first infers the relevant type parameters from the receiver. In this example, it fixes the element type as DerivedValue. The base-type comparer is then accepted through the contravariance of IEqualityComparer(Of T).
C# inference considers both the receiver and the comparer, resulting in BaseValue instead. Omitting explicit type arguments therefore changes the type of the resulting sequence.
Microsoft's VB team describes this receiver-first inference here:
https://devblogs.microsoft.com/vbteam/extension-methods-and-generics-extension-methods-part-5/
A workaround is to specify the type argument explicitly in the VB source:
Return values.Distinct(Of DerivedValue)(EqualityComparer(Of BaseValue).Default).ToDictionary(Function(value) value.Key)
- Dominant language
- C#
- Stars
- 916
- Forks
- 242
- Avg merge
- 2d 15h
- Merged PRs (30d)
- 9
Getting set up
- No Dockerfile or Docker Compose file
- Has a pull request template
- Read the contributing guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from icsharpcode/CodeConverter
-
VB -> C#
Difficulty 2/5 1-3 hours Newbie friendliness 72/100
icsharpcode/CodeConverter#1301 ·
Maintainers usually reply within 3 days
-
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
icsharpcode/CodeConverter#1271 · 1 comment ·
Maintainers usually reply within 3 days
-
VB -> C#
Difficulty 3/5 1-2 days Newbie friendliness 68/100
icsharpcode/CodeConverter#1300 ·
Maintainers usually reply within 3 days
-
VB -> C#
Difficulty 3/5 1-2 days Newbie friendliness 62/100
icsharpcode/CodeConverter#1299 ·
Maintainers usually reply within 3 days
-
VB -> C#
Difficulty 3/5 1-2 days Newbie friendliness 62/100
icsharpcode/CodeConverter#1298 ·
Maintainers usually reply within 3 days
All issues in icsharpcode/CodeConverter
Similar issues
-
Difficulty 1/5 Under an hour Newbie friendliness 72/100
-
Difficulty 2/5 1-3 hours Newbie friendliness 68/100
Facepunch/sbox-public#12284 ·
Maintainers usually reply within 6 days
-
bug untriaged
Difficulty 2/5 1-3 hours Newbie friendliness 67/100
Maintainers usually reply within 1 day
-
Difficulty 2/5 1-3 hours Newbie friendliness 65/100
CarlosAdrianM/Nesto#610 ·
-
[bug-bash] print maps a missing item's HTTP 404 to exit 1 instead of documented not-found exit 5Openbug bug-bash
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
Azure/CosmosDBShell#279 ·
Maintainers usually reply within 1 day