Version Used:
16.8.2
Steps to Reproduce:
https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMAWAbjzwyIGE8BvPI1kzANhLKIFkBDAJZQAFAEoWbZrjaz2xAG78ANhACmRALxEARDqoy5rUsQBG/AM5qAIoLBqAxsAD2YAJ5bd+yUbr8HABZqIiJKqmowROZWtvZOrm5ikQDWWgB8RMkAdGHqRIiZWdE2do4u7pH8cABWEBbAAGKCymoACvzAAX6BamIGsgC+PkTDAA5ggkrAGqRc9lXOUMoetk6Ci/zuADwiJplqbpF7xbFlCUnyGVW19U0t7Z3dQZ5QagDuRKvA61Cbbjt7ZIHI6YMyWEpxcqJEEENLiAzDYTTMC/ZTsLh7J5qLYAFThOP2hxIAFZcTCMg5nABbUYQaaRL4/P5ky5EOCCNYbdwSQysaRGVidMDOD5QCDKZT9NhDXADIA=
using System;
using System.Collections.Generic;
class C
{
static void Main()
{
string value = "";
string baseDirectory = "";
Cache((value, baseDirectory), k => k.value + k.baseDirectory, adjustFilePathCache);
}
private static readonly Dictionary<(string key, string baseDirectory), string> adjustFilePathCache = new Dictionary<(string key, string baseDirectory), string>();
internal static string Cache<T>(T key, Func<T, string> compute, Dictionary<T, string> dictionary)
{
throw null;
}
}
Expected Behavior:
Should compile?
Actual Behavior:
error CS1061: '(string, string baseDirectory)' does not contain a definition for 'value' and no accessible extension method 'value' accepting a first argument of type '(string, string baseDirectory)' could be found (are you missing a using directive or an assembly reference?)
@KirillOsenkov This behavior sounds reasonable to me.
The generic type T of the static Cache method is used in two places:
T key, and the tuple passed to it is (value, baseDirectory).Dictionary<T, string> dictionary, and the dictionary have the key as (string key, string baseDirectory).So, what should the compile infer the name of the first item? value or key? the compiler here preferred to choose none of them, and call it Item1.
For the second tuple item, because both are called baseDirectory, the compiler inferred the name correctly.
Here is a compiling version after making the name of the first item consistent:
https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMAWAbjzwyIGE8BvPI1kzANhLKIFkBDAJZQAFAEoWbZrjaz2xAG78ANhACmRALxEARDqoy5rUsQBG/AM5qAIoLBqAxsAD2YAJ5bd+yUbr8HABZqIiJKqmowROZWtvZOrm5ikQDWWgB8RMkAdGHqRIiZWdE2do4u7pH8cABWEBbAAGKCymoACvzAAX6BamIGsgC+PkTDAA5ggkrAGqRc9lXOUMoetk6Ci/zuADwiJkS5EfJRliVx5YmRJhlVtfVNLe2d3UGeUGoA7kSrwOtQm247PYHS6YMwnWJlBJJeRpcQGYbCaZgP7KdhcPbPNRbAAqsOxmTUbkuAFYcSCCBkHM4ALajCDTSLfX7/MkwohwQRrDbuCSGVjSIysTpgZyfKAQZTKfpsIa4AZAA===
Ah, makes sense, thanks for the explanation!
Most helpful comment
@KirillOsenkov This behavior sounds reasonable to me.
The generic type
Tof the staticCachemethod is used in two places:T key, and the tuple passed to it is(value, baseDirectory).Dictionary<T, string> dictionary, and the dictionary have the key as(string key, string baseDirectory).So, what should the compile infer the name of the first item?
valueorkey? the compiler here preferred to choose none of them, and call itItem1.For the second tuple item, because both are called
baseDirectory, the compiler inferred the name correctly.Here is a compiling version after making the name of the first item consistent:
https://sharplab.io/#v2:C4LgTgrgdgNAJiA1AHwAICYCMBYAUKgBgAJVMAWAbjzwyIGE8BvPI1kzANhLKIFkBDAJZQAFAEoWbZrjaz2xAG78ANhACmRALxEARDqoy5rUsQBG/AM5qAIoLBqAxsAD2YAJ5bd+yUbr8HABZqIiJKqmowROZWtvZOrm5ikQDWWgB8RMkAdGHqRIiZWdE2do4u7pH8cABWEBbAAGKCymoACvzAAX6BamIGsgC+PkTDAA5ggkrAGqRc9lXOUMoetk6Ci/zuADwiJkS5EfJRliVx5YmRJhlVtfVNLe2d3UGeUGoA7kSrwOtQm247PYHS6YMwnWJlBJJeRpcQGYbCaZgP7KdhcPbPNRbAAqsOxmTUbkuAFYcSCCBkHM4ALajCDTSLfX7/MkwohwQRrDbuCSGVjSIysTpgZyfKAQZTKfpsIa4AZAA===