Home > Software engineering >  Calling a T Method and converting results to string C#
Calling a T Method and converting results to string C#

Time:03-23

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);
  • Related