Rules S4018: Suggestion to improve it

Hello,
my code trigger the rule S4018: All type parameters should be used in the parameter list to enable type inference.

My code is :

public T Foo<T>(string bar)
{

}

I found the issue which is the origin of this rule, and I understand why it is created.

Since it is a good suggestion, I think the rule can be more valuable if it is modified to check if a generic type is used in a function definition. I agree it is not the initial purpose of this rule, but I think this check can help improve the quality of code, and can help to reduce the usage of generic if it is not needed.

I would say this rule is not particularly actionable. If you need something like T CreateT<T>(), the caller will have to specify the type parameter. Delegating the creation to a FooCreator<T> typically does not help, since obtaining the FooCreator<T> tends to result in a similar problem.

Sometimes, there may be ways to avoid the <T>, though:

  • If the return value of Foo will often be returned or passed to another method directly, try adding a method that returns an intermediate struct and adding an implicit conversion operator from the intermediate struct to the desired type. The conversion operator may need to be defined on the desired type or on the intermediate struct; with generics often only one of the two will work. The T CreateT<T>() will still be useful for cases like Task.FromResult.
  • If there is not only a type parameter to create, but also one or more type parameters that correspond to method parameters, C# will not infer the latter even if it would be possible. A workaround is to remove the type parameter to create from the original method and return an intermediate struct instead. The intermediate struct has a method with a single type parameter, the type to create. The original method’s type parameters can then be inferred.

This kind of tricks is worth it if there is a lot of calling code, but it is uncommon. If there is not a lot of calling code, it might be better to have some ugly type parameter specifications.

Hi,

Welcome to the community, @jmagano-ena!

Could either / both of you provide the context where you’re seeing this? I’d like to confirm it’s from a current/latest version of the underlying language analyzer before I flag it for the language experts.

 
Thx,
Ann

For ganncamp (sorry, I can’t yet mention you directly): Sure, the version of sonarqube in my side is : Enterprise Edition v2025.3.1 (109879)

For jilles-sg: In my context, bar is a value of an enum, and on each value there are some attribute attached. The purpose of the function Foo is to extract a specific attribute (of type T) from a value of this enum, and return this attribute. Since there are multiples attributes on a value, the use of a generic function is logical.

Hi,

Thanks @jmagano-ena! I’ve flagged this for the language experts.

 
Ann

1 Like

@jmagano-ena could you provide your suggestion of improvement in form or compliant - non-compliant example (like it is here)?
Thanks a lot for contributing!

EDIT: Wrong user - thanks for the correction @jmagano-ena :smile:
Indeed the message is for you.

I think your message is for me :slight_smile:

If I take the existing examples:

Noncompliant code example

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void MyMethod<T>()  // Noncompliant
    {
        // this method can only be invoked by providing the type argument e.g. 'MyMethod<int>()'
    }
  }
}

Compliant solution

using System;

namespace MyLibrary
{
  public class Foo
  {
    public void MyMethod<T>(T param)
    {
        // type inference allows this to be invoked 'MyMethod(arg)'
    }

    public T MyMethod2<T>()
    {
        // type inference (using function returns, variable assignation,…) allows this to be invoked 'MyMethod2()'
    }
  }
}

Hello @jmagano-ena,

This case has already been discussed regarding this rule and the decision was not to proceed.
Please take a look here.

Let me know if I’ve misunderstood.

1 Like

Thanks @Mary !

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.