Question

I saw this interesting question which talks about T declaration at the class level and the same letter T ( different meaning) at the method level.

So I did a test.

  static void Main(string[] args)
        {
            var c = new MyClass<int>(); //T is int
            c.MyField = 1;
            c.MyProp = 1;
            c.MyMethod("2");
        }


        public class MyClass<T>
        {
            public T MyField;
            public T MyProp { get; set; }
            public void MyMethod<T>(T k)
            {
            }
        }

As Eric said , the compiler does warn.

But Hey , what happened to type safety ? I assume there is a type safety at the Method level but what about the global context of the class where T already has been declared.

I mean if someone would have asked me , I would guess there should be an error there and not a warning.

Why the compiler allows that? ( I would love to hear a reasonable answer)

Was it helpful?

Solution

Interesting question. Type safety is preserved here. Behaviour is alike global and local variables. In MyMethod type T is unambiguous. We can also create and return new instance of MyClass as follows:

public class MyClass<T>
{
    public T MyField;
    public T MyProp { get; set; }
    public MyClass<T> MyMethod<T>(T k)
    {
        return new MyClass<T>();
    }
}

The program:

static void Main()
{
    var c = new MyClass<int>(); //T is int
    c.MyField = 1;
    c.MyProp = 1;

    var myClass = c.MyMethod("2");
    myClass.MyField = "2";
    myClass.MyField = "4";
}

There is no compilation error and it shouldn't be, because type safety is preserved. Program can be compiled. There is no ambiguity.

The warning should be there, because T overrides its class level counterpart and there is no simple way in MyMethod to obtain that global T. It also obscures legibility.

MSDN says about flexibility and good practice in Generic Methods (C# Programming Guide):

If you define a generic method that takes the same type parameters as the containing class, the compiler generates warning CS0693 because within the method scope, the argument supplied for the inner T hides the argument supplied for the outer T. If you require the flexibility of calling a generic class method with type arguments other than the ones provided when the class was instantiated, consider providing another identifier for the type parameter of the method.

OTHER TIPS

This is not a type-safety issue. It is only a readability issue - that's why it's just a warning. (Also, T hides the outer T.)

If change MyMethod() to:

public void MyMethod<T>(T k)
{
    Console.WriteLine(typeof(T).FullName);
}

It'll print out System.String for your sample code, proving that it is getting the correct type.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top