泛型类型冲突

本文关键字:冲突 泛型类型 | 更新日期: 2023-09-27 18:01:15

我看到了这个有趣的问题,它在类级别谈论T声明,在方法级别谈论相同的字母T(不同的含义(。

所以我做了一个测试。

  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)
            {
            }
        }

正如Eric所说,编译器确实发出了警告。

但是嘿,打字安全怎么了?我假设方法级别存在类型安全性,但已经声明T的类的全局上下文又如何呢。

我的意思是,如果有人问我,我想那里应该有一个错误,而不是警告

为什么编译器允许这样做?(我很想听到一个合理的答案(

泛型类型冲突

有趣的问题。此处保留了类型安全性。行为是全局变量和局部变量。在MyMethod中,类型T是明确的。我们还可以创建并返回MyClass的新实例,如下所示:

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

程序:

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";
}

没有编译错误,也不应该出现,因为类型安全性得到了保护。程序可以编译。没有歧义。

警告应该存在,因为T覆盖其类级对应项,并且在MyMethod中没有简单的方法来获得全局T。它也模糊了易读性。

MSDN谈到通用方法的灵活性和良好实践(C#编程指南(:

如果您定义的泛型方法采用与包含类相同的类型参数,编译器会生成警告CS0693,因为在方法范围内,为内部T提供的参数会隐藏为外部T提供的自变量。如果您需要灵活地使用类实例化时提供的类型参数以外的类型参数调用泛型类方法,考虑为方法的类型参数提供另一个标识符。

这不是类型安全问题。这只是一个可读性问题——这就是为什么它只是一个警告。(同样,T隐藏外部T。(

如果将MyMethod((更改为:

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

它将为您的示例代码打印System.String,证明它得到了正确的类型。