简体   繁体   中英

KeyValuePair type inference inside Dictionary initializer

I'm building a Dictionary with key type KeyValuePair . When using KeyValuePair.Create inside Dictionary initializer it doesn't require template types and it inferred the type correctly, the following compiles correctly without even a warning:

private static readonly IDictionary<KeyValuePair<Market, MarketData>, string> channelDict =
    new Dictionary<KeyValuePair<Market, MarketData>, string> {
        { KeyValuePair.Create(Market.USD, MarketData.Trade), "trades" },
        ...
};

Now the code was reorganized, type Market and MarketData was moved to a separate project and namespace, and the namespace is imported by using statements at the top of the file, but now the same code won't compile, it throws this error:

error CS0305: Using the generic type 'KeyValuePair<TKey, TValue>' requires 2 type arguments

I can be sure that using namespace imported correctly, because simple add private Market _m; didn't produce any error, what's more, the definition of the dictionary:

private static readonly IDictionary<KeyValuePair<Market, MarketData>, string> channelDict =
    new Dictionary<KeyValuePair<Market, MarketData>, string>

did not produce error neither, it is the Create method cannot compile:

KeyValuePair.Create(Market.USD, MarketData.Trade)

So why it cannot infer the type now when type arguments is in another namespace, while it can before?

After done some digging, I just found that the problem is not about initialization of KeyValuePair , rather it's because difference of target frameworks.

Initially all the code are in the same .NET Core console app, set target framework as netcoreapp2.0 , and from the docs, in .NET Core 2.0, KeyValuePair is a static class with a static method Create , which will infer the type arguments correctly.

Then when I reorganized the code, I moved this part to a class library, by default, dotnet tool will set netstandard2.0 as its target framework, however, KeyValuePair and Create is not available in netstandard2.0 , as you can see from docs , it says:

This API is not supported in the currently selected framework.

That's why the code failed to compile when moved to a library project, there is only generic KeyValuePair<K, V> version in netstandard framework.

As a workaround, I verified when I set target framework in the .csproj file to netcoreapp2.0 and outputtype to library , it succeeded to compile.

OTOH, library project uses netstandard by default because it makes sure the library is usable among different platform targets, so the better fix would be do not use static KeyValuePair.Create in library code, and use generic version instead: new KeyValuePair<K, V>(k, v) .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM