为什么我必须在泛型类的静态方法调用上使用<T>

Sve*_*art 3 c# generics

我遵循这个泛型类的例子.因为我不想用测试代码填充我的项目的主要功能,所以我想创建一个运行代码示例的静态展示函数.

我的代码:

namespace Syntax
{
    public class GenericClass<T>
    {
        private class Node
        {
            private T data;
            private Node next;

            public Node(T t)
            {
                next = null;
                data = t;
            }

            public Node Next { get { return next; } set { next = value; } }
            public T Data { get { return data; } set { data = value; } }
        }


        private Node head;
        public GenericClass()
        {
            head = null;
        }

        public void AddHead(T t)
        {
            Node n = new Node(t);
            n.Next = head;
            head = n;
        }

        public IEnumerator<T> GetEnumerator()
        {
            Node current = head;
            while (current != null)
            {
                yield return current.Data;
                current = current.Next;
            }
        }


        public static void Showcase()
        {
            GenericClass<int> list = new GenericClass<int>();

            for(int x = 0; x <10; x++)
            {
                list.AddHead(x);
            }

            System.Console.WriteLine("\nPrinting generic class using ints.");
            foreach (int i in list)
            {
                System.Console.Write(i + ", ");
            }

            GenericClass<char> listChars = new GenericClass<char>();
            string abc = "abcdefghijklmnopqrstuvw";
            foreach (char c in abc)
            {
                listChars.AddHead(c);
            }

            System.Console.WriteLine("\n\nPrinting generic class using chars.");
            foreach (var c in listChars)
            {
                System.Console.Write(c + ", ");
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

除了静态Showcase方法之外,它几乎与链接的示例完全相同.

现在在我的主要方法中我可以打电话:

GenericClass<int>.Showcase();
Run Code Online (Sandbox Code Playgroud)

我可以用以下代码更改代码:

GenericClass<string>.Showcase();
GenericClass<char>.Showcase();
Run Code Online (Sandbox Code Playgroud)

它仍然有效.

如果我能做到的话

GenericClass<int> test = new GenericClass<int>();
test.Showcase();
Run Code Online (Sandbox Code Playgroud)

对我来说完全有意义的是它需要一个类型,因为我可以在测试时调用其他方法.

我没有看到添加类型的优点,需要添加一个随机类只能导致我脑海中的混乱,为什么不是静态方法的语法genericClass<T>.StaticMethod();,例如将类型添加到静态方法dosnt add anythig(或者它?).那么为什么我需要<T>在泛型类上调用静态方法时使用呢?

Bol*_*ock 5

因为类是通用的,所以使用它需要一个类型参数,即使静态方法本身是非泛型的.类型参数不是可选的.

这就是为什么在泛型类上使用静态成员会导致CA1000的原因 - 因为这样做需要您提供一个类型参数,即使它最终与该静态成员无关.如果要创建与泛型类相关的静态方法,请将它们放在非泛型辅助类中.


Dam*_*ver 5

因为您还没有创建一个名为的类GenericClass,所以您创建了一个名为的开放泛型类GenericClass<T>.

没有什么可以阻止你GenericClass在同一个命名空间中创建一个类,也没有什么可以阻止你创建一个名为的类GenericClass<T1,T2>.所有这些都可以存在于同一名称空间中,并且它们之间没有明确或隐含的关系,除非您声明一个.

所以,如果你想在"一个类型参数中通用的GenericClass类"上调用一个静态方法,你必须通过提供一个类型参数以某种方式说明,并且你已经找到了如何做到这一点.

有人可能会说,如果静态方法不使用类型参数,那么它是多余的 - 那么为什么不能仅使用仍然打开的类型参数来调用它?嗯,首先是因为那必须是新的语法才能允许这种情况发生1.第二,如果您的方法访问任何静态字段会发生什么?对于泛型类型,用作类型参数的每个唯一类型都会导致存在一组新的静态字段.


为什么不是静态方法的语法genericClass<T>.StaticMethod();,例如...

在我的初步答复之后添加了上述内容,我希望在下面的脚注1中已经解决了这个问题.但是,如果不清楚,这种简单的语法将无法正常工作.你需要发明一些新语法,因为你可能有:

class Abc<T> {
   void DoSomething(){
       GenericClass<T>.StaticMethod();
   }
}
Run Code Online (Sandbox Code Playgroud)

要么

namespace X {
   class T {
   }
   class Abc {
      void DoSomething(){
          GenericClass<T>.StaticMethod();
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

在上述两个示例T中,已经由外部范围定义.因此,您需要一些其他方式来说明"我不想为此通用的第一个类型参数提供类型".


1例如 可以说GenericClass<T>.Showcase.任何允许它的新语法都不是那么简单.因为a)T调用上下文中的范围中可能存在泛型类型参数,或者b)泛型类型参数的名称可能与调用上下文中的范围内的某些其他类型名称冲突.