简体   繁体   中英

Func<T, TResult> parameter - The type arguments for method cannot be inferred from the usage

I have the following method

Func<string,IEnumerable<dynamic>> getLpVideos = delegate(string language)
{
    var id = GetBy(language);
    return new List();
}; 

I want to pass a parameter like that to a generic method, but I am confused with how to use this parameter at GetObjectFromMemoryCacheWithDefParams and how to call GetObjectFromMemoryCacheWithDefParams :

public T GetObjectFromMemoryCacheWithDefParams<T>(
    string key, Func<string, T> defGetValueFunc) where T : class
{
    var result = _cache.Get(key) as T;

    return result ?? defGetValueFunc();//here error
}


//The type arguments for method cannot be inferred from the usage
var result = CacheService
    .GetObjectFromMemoryCacheWithDefParams(casheName, getLpVideos(lng));

Only when the type parameter is explicitly provided does it work.

You are not passing in a Func<string, T> as expected. You're passing an IEnumerable<dynamic> instead, which is a dynamic expression evaluated at runtime. Note that getLpVideos(lng) is not a function, it is a function invocation , which means its return value is used as the second parameter, not the function itself. You need this instead:

var result = CacheService
    .GetObjectFromMemoryCacheWithDefParams(casheName, getLpVideos);

Additionally, you need to fix your function invocation within the GetObjectFromMemoryCacheWithDefParams method -- it expects an input parameter, which you don't supply:

So change this:

return result ?? defGetValueFunc();

to this:

return result ?? defGetValueFunc(key);

If I understand your problem correctly, you just want to get the call to work. In that case you just need to tell it explicitly what type T is. In your case that is IEnumerable<dynamic> . So you can just call

var result = CacheService.
             GetObjectFromMemoryCacheWithDefParams<IEnumerable<dynamic>>(
                    casheName, 
                    getLpVideos(lng)
             );

You need to pass a string into defGetValueFunc and specify the type of T explicitly

public T GetObjectFromMemoryCacheWithDefParams<T>(string key, Func<string,T> defGetValueFunc) where T : class
{
  var result = _cache.Get(key) as T;    
  return result ?? defGetValueFunc(*somestring*);
}


var result = CacheService.GetObjectFromMemoryCacheWithDefParams<IEnumerable<dynamic>>(casheName, getLpVideos(lng)  );

Are you sure that's exactly the code you're trying to compile? And does the error actually happen exactly where you say it does?

If so, then it appears to me that the problem with your code is that you are simply not invoking the delegate parameter correctly. You are passing a delegate instance that requires a single string parameter to be passed to it. But in your code, you are not passing any parameter:

public T GetObjectFromMemoryCacheWithDefParams<T>(
    string key, Func<string, T> defGetValueFunc) where T : class
{
    var result = _cache.Get(key) as T;

    return result ?? defGetValueFunc(--> you need a parameter here! <--);//here error
}

I don't know what parameter you should be passing, as the anonymous method you've included in your post doesn't even use the parameter (except to retrieve a value that is ignored). But you have to pass something.

I don't think there's actually anything wrong with type inference here. This simple example, which is essentially identical to yours (except that I invoke the delegate correctly) compiles just fine:

static T Method<T>(string s, Func<string, T> f) where T : class
{
    return f(s);
}

static void OtherMethod()
{
    Func<string, IEnumerable<dynamic>> f = l => new List<object>();

    Method("foo", f);
}

So clearly the compiler can infer the correct type, given correct code. :)

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