I have the following generic method:
public T GetUserPreference<T>(string keyName, string programName)
{
string json = preferencesRepository.GetUserPreference(keyName, programName);
if (json != null)
{
try
{
return JsonSerializer.Deserialize<T>(json);
}
catch (Exception ex)
{
Logger.LogError(ex, nameof(GetUserPreference));
}
}
return default(T);
}
Here is the code for my GetUserPreference
method:
public string GetUserPreference(string key, string programName)
{
string query = { Retrieving data from a varbinary field in SQL }
List<SqlParameter> sqlParams = new List<SqlParameter>
{
new SqlParameter("@Username", SqlDbType.VarChar) { Value = GlobalUserName },
new SqlParameter("@ProgramName", SqlDbType.VarChar) { Value = programName },
new SqlParameter("@KeyName", SqlDbType.VarChar) { Value = key }
};
try
{
object preferenceResult = Data.ExecuteScalar(query, SqlServerConnectionString, sqlParams.ToArray());
return preferenceResult == null ? null : Encoding.UTF8.GetString((byte[])preferenceResult);
}
catch (Exception ex)
{
logger.LogError(ex, "");
}
return null;
}
I tried calling it like this:
string preference = preferencesService.GetUserPreference(key, programName);
But I get the following error:
The type arguments for method 'PreferencesService.GetUserPreference(string, string)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
The Method it is being called from is as follows:
[ApiVersion("1.0")]
[HttpGet("v{version:apiVersion}/Preferences", Name = "Get User Preference")]
public IActionResult Get(string key, string programName)
{
string preference = preferencesService.GetUserPreference<T>(key, programName);
if (preference == null)
{
return new NoContentResult();
}
return Content(preference);
}
How do I call this generic method ?
CodePudding user response:
You can explicitly specify the type argument of a generic method by adding it like in the definition:
string preference = preferencesService.GetUserPreference<TheActualTypeYouKnowItIs>(key, programName);
C# compiler can't guess it in this context, basically since it would return string for any type argument.
CodePudding user response:
You can only use T
(or any type filler) if you are in Generic context (a Generic method or class).
For example, your first method
public T GetUserPreference<T>(string keyName, string programName)
However, in a non-generic caller, you have to specify the type you want to invoke the generic method with. So
string preference = preferencesService.GetUserPreference<T>(key, programName);
//Wrong in non generic context
Here you should use and actual type instead of T.
Now, as per the implementation you have for GetUserPreference<T>
, the T
is used to determine the type to be used for deserializing. So you should use the type you expect your result to be in.
Example,
string preference = preferencesService.GetUserPreference<string>(key, programName);
CodePudding user response:
You have to define T type, since this type is using to deserialize JsonSerializer.Deserialize< T >(json). If for some reasons you don't know type, you can use object as type, but basically it will be just parsed. And you have a bug return type should be T, not string
var preference = preferencesService.GetUserPreference<object>(key, programName);
or if you really expecting string it should be
var preference = preferencesService.GetUserPreference<string>(key, programName);