Can I help the C# compiler to infer this type?











up vote
5
down vote

favorite
1












I'm having an issue with type inference and the C# compiler. Having read this question and this question I think I understand why it isn't working: what I would like to know is if there is any way I can work-around the problem in order to get my preferred calling semantics.



Here is some code that illustrates my problem (sorry for the length, this is the shortest I could reduce it to):



using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace StackOverflow
{
interface IQuery<TResult> { }

class MeaningOfLifeQuery : IQuery<int> { }

interface IQueryHandler<TQuery, TResult> where TQuery : class, IQuery<TResult>
{
Task<TResult> ExecuteAsync(TQuery query);
}

class MeaningOfLifeQueryHandler : IQueryHandler<MeaningOfLifeQuery, int>
{
public Task<int> ExecuteAsync(MeaningOfLifeQuery query)
{
return Task.FromResult(42);
}
}

interface IRepository
{
Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query);
Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>;
}

class Repository : IRepository
{
public Repository(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

readonly IServiceProvider _serviceProvider;

public async Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query)
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync((dynamic) query);
}

public async Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(typeof(TQuery), typeof(TResult));
var handler = (IQueryHandler<TQuery, TResult>) _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync(query);
}
}

class Program
{
static void Main(string args)
{
var services = new ServiceCollection();
services.AddTransient<IQueryHandler<MeaningOfLifeQuery, int>, MeaningOfLifeQueryHandler>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

var repository = new Repository(serviceProvider);
var query = new MeaningOfLifeQuery();
int result = repository.ExecuteQueryDynamicallyAsync(query).Result;
result = repository.ExecuteQueryStaticallyAsync<MeaningOfLifeQuery, int>(query).Result;

// result = repository.ExecuteQueryStaticallyAsync(query).Result;
// Doesn't work: type arguments cannot be inferred
}
}
}


Basically I want to get the repository to execute queries simply by calling an ExecuteAsync method and passing the query. To make this work I have to use dynamic to resolve the query handler type at runtime, as per ExecuteQueryDynamicallyAsync. Alternatively, I can specify both the query type and result type as type parameters when calling the method (as per ExecuteQueryStaticallyAsync) but this is obviously quite a wordy call, particularly when the query and/or return types have long names.



I can get the compiler to infer both types using a method signature like this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored)
where TQuery : class, IQuery<TResult>


which allows me to do something like this:



var query = new MeaningOfLifeQuery();
...
... ExecuteQueryAsync(query, default(int)) ...


but then I have to pass a dummy value (that gets ignored) to the method with each call. Changing the signature to this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored = default(TResult))
where TQuery : class, IQuery<TResult>


to try to avoid passing in the value when calling doesn't work, as the compiler can no longer infer the result type (ie. back to square one).



I'm at a bit of a loss as to how I can solve this problem, or even if it is solvable. My only options seem to be to stick with the simple calling semantics (but have to rely upon dynamic) or to change my architecture in some way. Is there any way I can get the calling semantics I want?










share|improve this question


















  • 1




    The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
    – Hans Passant
    Nov 19 at 12:24












  • Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
    – NetMage
    2 days ago












  • Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
    – NetMage
    2 days ago










  • Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
    – NetMage
    2 days ago












  • @NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
    – Steven Rands
    2 days ago















up vote
5
down vote

favorite
1












I'm having an issue with type inference and the C# compiler. Having read this question and this question I think I understand why it isn't working: what I would like to know is if there is any way I can work-around the problem in order to get my preferred calling semantics.



Here is some code that illustrates my problem (sorry for the length, this is the shortest I could reduce it to):



using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace StackOverflow
{
interface IQuery<TResult> { }

class MeaningOfLifeQuery : IQuery<int> { }

interface IQueryHandler<TQuery, TResult> where TQuery : class, IQuery<TResult>
{
Task<TResult> ExecuteAsync(TQuery query);
}

class MeaningOfLifeQueryHandler : IQueryHandler<MeaningOfLifeQuery, int>
{
public Task<int> ExecuteAsync(MeaningOfLifeQuery query)
{
return Task.FromResult(42);
}
}

interface IRepository
{
Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query);
Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>;
}

class Repository : IRepository
{
public Repository(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

readonly IServiceProvider _serviceProvider;

public async Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query)
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync((dynamic) query);
}

public async Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(typeof(TQuery), typeof(TResult));
var handler = (IQueryHandler<TQuery, TResult>) _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync(query);
}
}

class Program
{
static void Main(string args)
{
var services = new ServiceCollection();
services.AddTransient<IQueryHandler<MeaningOfLifeQuery, int>, MeaningOfLifeQueryHandler>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

var repository = new Repository(serviceProvider);
var query = new MeaningOfLifeQuery();
int result = repository.ExecuteQueryDynamicallyAsync(query).Result;
result = repository.ExecuteQueryStaticallyAsync<MeaningOfLifeQuery, int>(query).Result;

// result = repository.ExecuteQueryStaticallyAsync(query).Result;
// Doesn't work: type arguments cannot be inferred
}
}
}


Basically I want to get the repository to execute queries simply by calling an ExecuteAsync method and passing the query. To make this work I have to use dynamic to resolve the query handler type at runtime, as per ExecuteQueryDynamicallyAsync. Alternatively, I can specify both the query type and result type as type parameters when calling the method (as per ExecuteQueryStaticallyAsync) but this is obviously quite a wordy call, particularly when the query and/or return types have long names.



I can get the compiler to infer both types using a method signature like this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored)
where TQuery : class, IQuery<TResult>


which allows me to do something like this:



var query = new MeaningOfLifeQuery();
...
... ExecuteQueryAsync(query, default(int)) ...


but then I have to pass a dummy value (that gets ignored) to the method with each call. Changing the signature to this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored = default(TResult))
where TQuery : class, IQuery<TResult>


to try to avoid passing in the value when calling doesn't work, as the compiler can no longer infer the result type (ie. back to square one).



I'm at a bit of a loss as to how I can solve this problem, or even if it is solvable. My only options seem to be to stick with the simple calling semantics (but have to rely upon dynamic) or to change my architecture in some way. Is there any way I can get the calling semantics I want?










share|improve this question


















  • 1




    The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
    – Hans Passant
    Nov 19 at 12:24












  • Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
    – NetMage
    2 days ago












  • Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
    – NetMage
    2 days ago










  • Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
    – NetMage
    2 days ago












  • @NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
    – Steven Rands
    2 days ago













up vote
5
down vote

favorite
1









up vote
5
down vote

favorite
1






1





I'm having an issue with type inference and the C# compiler. Having read this question and this question I think I understand why it isn't working: what I would like to know is if there is any way I can work-around the problem in order to get my preferred calling semantics.



Here is some code that illustrates my problem (sorry for the length, this is the shortest I could reduce it to):



using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace StackOverflow
{
interface IQuery<TResult> { }

class MeaningOfLifeQuery : IQuery<int> { }

interface IQueryHandler<TQuery, TResult> where TQuery : class, IQuery<TResult>
{
Task<TResult> ExecuteAsync(TQuery query);
}

class MeaningOfLifeQueryHandler : IQueryHandler<MeaningOfLifeQuery, int>
{
public Task<int> ExecuteAsync(MeaningOfLifeQuery query)
{
return Task.FromResult(42);
}
}

interface IRepository
{
Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query);
Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>;
}

class Repository : IRepository
{
public Repository(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

readonly IServiceProvider _serviceProvider;

public async Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query)
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync((dynamic) query);
}

public async Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(typeof(TQuery), typeof(TResult));
var handler = (IQueryHandler<TQuery, TResult>) _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync(query);
}
}

class Program
{
static void Main(string args)
{
var services = new ServiceCollection();
services.AddTransient<IQueryHandler<MeaningOfLifeQuery, int>, MeaningOfLifeQueryHandler>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

var repository = new Repository(serviceProvider);
var query = new MeaningOfLifeQuery();
int result = repository.ExecuteQueryDynamicallyAsync(query).Result;
result = repository.ExecuteQueryStaticallyAsync<MeaningOfLifeQuery, int>(query).Result;

// result = repository.ExecuteQueryStaticallyAsync(query).Result;
// Doesn't work: type arguments cannot be inferred
}
}
}


Basically I want to get the repository to execute queries simply by calling an ExecuteAsync method and passing the query. To make this work I have to use dynamic to resolve the query handler type at runtime, as per ExecuteQueryDynamicallyAsync. Alternatively, I can specify both the query type and result type as type parameters when calling the method (as per ExecuteQueryStaticallyAsync) but this is obviously quite a wordy call, particularly when the query and/or return types have long names.



I can get the compiler to infer both types using a method signature like this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored)
where TQuery : class, IQuery<TResult>


which allows me to do something like this:



var query = new MeaningOfLifeQuery();
...
... ExecuteQueryAsync(query, default(int)) ...


but then I have to pass a dummy value (that gets ignored) to the method with each call. Changing the signature to this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored = default(TResult))
where TQuery : class, IQuery<TResult>


to try to avoid passing in the value when calling doesn't work, as the compiler can no longer infer the result type (ie. back to square one).



I'm at a bit of a loss as to how I can solve this problem, or even if it is solvable. My only options seem to be to stick with the simple calling semantics (but have to rely upon dynamic) or to change my architecture in some way. Is there any way I can get the calling semantics I want?










share|improve this question













I'm having an issue with type inference and the C# compiler. Having read this question and this question I think I understand why it isn't working: what I would like to know is if there is any way I can work-around the problem in order to get my preferred calling semantics.



Here is some code that illustrates my problem (sorry for the length, this is the shortest I could reduce it to):



using System;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;

namespace StackOverflow
{
interface IQuery<TResult> { }

class MeaningOfLifeQuery : IQuery<int> { }

interface IQueryHandler<TQuery, TResult> where TQuery : class, IQuery<TResult>
{
Task<TResult> ExecuteAsync(TQuery query);
}

class MeaningOfLifeQueryHandler : IQueryHandler<MeaningOfLifeQuery, int>
{
public Task<int> ExecuteAsync(MeaningOfLifeQuery query)
{
return Task.FromResult(42);
}
}

interface IRepository
{
Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query);
Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>;
}

class Repository : IRepository
{
public Repository(IServiceProvider serviceProvider)
{
_serviceProvider = serviceProvider;
}

readonly IServiceProvider _serviceProvider;

public async Task<TResult> ExecuteQueryDynamicallyAsync<TResult>(IQuery<TResult> query)
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(query.GetType(), typeof(TResult));
dynamic handler = _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync((dynamic) query);
}

public async Task<TResult> ExecuteQueryStaticallyAsync<TQuery, TResult>(TQuery query)
where TQuery : class, IQuery<TResult>
{
Type handlerType = typeof(IQueryHandler<,>).MakeGenericType(typeof(TQuery), typeof(TResult));
var handler = (IQueryHandler<TQuery, TResult>) _serviceProvider.GetRequiredService(handlerType);
return await handler.ExecuteAsync(query);
}
}

class Program
{
static void Main(string args)
{
var services = new ServiceCollection();
services.AddTransient<IQueryHandler<MeaningOfLifeQuery, int>, MeaningOfLifeQueryHandler>();
IServiceProvider serviceProvider = services.BuildServiceProvider();

var repository = new Repository(serviceProvider);
var query = new MeaningOfLifeQuery();
int result = repository.ExecuteQueryDynamicallyAsync(query).Result;
result = repository.ExecuteQueryStaticallyAsync<MeaningOfLifeQuery, int>(query).Result;

// result = repository.ExecuteQueryStaticallyAsync(query).Result;
// Doesn't work: type arguments cannot be inferred
}
}
}


Basically I want to get the repository to execute queries simply by calling an ExecuteAsync method and passing the query. To make this work I have to use dynamic to resolve the query handler type at runtime, as per ExecuteQueryDynamicallyAsync. Alternatively, I can specify both the query type and result type as type parameters when calling the method (as per ExecuteQueryStaticallyAsync) but this is obviously quite a wordy call, particularly when the query and/or return types have long names.



I can get the compiler to infer both types using a method signature like this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored)
where TQuery : class, IQuery<TResult>


which allows me to do something like this:



var query = new MeaningOfLifeQuery();
...
... ExecuteQueryAsync(query, default(int)) ...


but then I have to pass a dummy value (that gets ignored) to the method with each call. Changing the signature to this:



Task<TResult> ExecuteQueryAsync<TQuery, TResult>(TQuery query, TResult ignored = default(TResult))
where TQuery : class, IQuery<TResult>


to try to avoid passing in the value when calling doesn't work, as the compiler can no longer infer the result type (ie. back to square one).



I'm at a bit of a loss as to how I can solve this problem, or even if it is solvable. My only options seem to be to stick with the simple calling semantics (but have to rely upon dynamic) or to change my architecture in some way. Is there any way I can get the calling semantics I want?







c# type-inference






share|improve this question













share|improve this question











share|improve this question




share|improve this question










asked Nov 19 at 12:11









Steven Rands

3,1551941




3,1551941








  • 1




    The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
    – Hans Passant
    Nov 19 at 12:24












  • Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
    – NetMage
    2 days ago












  • Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
    – NetMage
    2 days ago










  • Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
    – NetMage
    2 days ago












  • @NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
    – Steven Rands
    2 days ago














  • 1




    The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
    – Hans Passant
    Nov 19 at 12:24












  • Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
    – NetMage
    2 days ago












  • Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
    – NetMage
    2 days ago










  • Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
    – NetMage
    2 days ago












  • @NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
    – Steven Rands
    2 days ago








1




1




The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
– Hans Passant
Nov 19 at 12:24






The compiler must be able to infer the type parameters from the method parameters. One parameter, two types to infer. It has no shot at int. Nope, the return type plays no role. A hacky way is to add an extra parameter to represent the default return value. That is however easy to push too far.
– Hans Passant
Nov 19 at 12:24














Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
– NetMage
2 days ago






Is there any reason you can't remove TQuery and just replace with IQuery<TResult> everywhere? What does having a separate TQuery gain you?
– NetMage
2 days ago














Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
– NetMage
2 days ago




Unfortunately constraints are not part of the signature and won't help you with type inference, and since TResult is part of your return value, you can't infer in pieces, that I can see.
– NetMage
2 days ago












Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
– NetMage
2 days ago






Also, the LDM decided type inference from constraints is a breaking change and dropped it. Sometimes it feels like we need C#+ to fix C#.
– NetMage
2 days ago














@NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
– Steven Rands
2 days ago




@NetMage Two main reasons. (1) The ExecuteAsync method in each query handler would no longer be strongly typed, requiring a cast. (2) The dependency injection would no longer work: I need to ask the service provider to "give me a handler for this type of query", but I'd have no way of specifying the type of the query.
– Steven Rands
2 days ago

















active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














 

draft saved


draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53374391%2fcan-i-help-the-c-sharp-compiler-to-infer-this-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown






























active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes
















 

draft saved


draft discarded



















































 


draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53374391%2fcan-i-help-the-c-sharp-compiler-to-infer-this-type%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Can a sorcerer learn a 5th-level spell early by creating spell slots using the Font of Magic feature?

Does disintegrating a polymorphed enemy still kill it after the 2018 errata?

A Topological Invariant for $pi_3(U(n))$