代码之家  ›  专栏  ›  技术社区  ›  Sektor

c语言中泛型的比较#

  •  6
  • Sektor  · 技术社区  · 6 年前

    为什么这个代码打印错误?

        class Program
    {
        public static void OpTest<T>(T s, T t) where T : class
        {
            Console.WriteLine(s == t);
        }
    
        static void Main()
        {
            string s1 = "string";
            System.Text.StringBuilder sb = new System.Text.StringBuilder(s1);
            string s2 = sb.ToString();
            OpTest(s1, s2);
        }
    }
    

    我是否正确理解比较时,它们不是作为字符串,而是作为对象进行比较,这就是为什么不比较它们的值,而是比较它们指向的地址?

    3 回复  |  直到 6 年前
        1
  •  3
  •   DavidG    6 年前

    docs for the == operator 以下内容:

    对于预定义的值类型,相等运算符( == )回报 true 如果其操作数的值相等, false 否则。对于除 string 我是说, == 回报 如果它的两个操作数引用同一个对象。对于 一串 类型, == 比较字符串的值。

    自从 T 不能保证是值类型,因为它是泛型的,编译器必须假定它是引用类型。

        2
  •  2
  •   scharette    6 年前

    我通常会在评论中同意你的观点,但你的例子特别好。

    我是否正确理解比较时,它们不是作为字符串,而是作为对象进行比较,这就是为什么不比较它们的值,而是比较它们指向的地址?

    事实并非如此。

    如所述 == 文档,

    对于字符串以外的引用类型, == 如果其两个操作数引用同一对象,则返回true。对于 string 类型, == 比较字符串的值。

    在您的特定情况下,原因是在比较它们之前,您将它们转换为泛型。但如果这些是字符串对象, 价值 会被比较。

        3
  •  1
  •   Dan Wilson    6 年前

    我发现创建一个非泛型 OpTest 方法来确认发生了什么。泛型方法将参数视为 Object 键入但不使用 == 过载 String ,这是比较值的特殊情况。

    在这两种情况下,参数都是类型 字符串 但是泛型方法在进行比较时“泛型地”对待它们。

    void Main()
    {
        string s1 = "string";
        System.Text.StringBuilder sb = new System.Text.StringBuilder(s1);
        string s2 = sb.ToString();
        TestClass.OpTest(s1, s2);
        TestClass.OpTest<string>(s1, s2);
    
        // OpTest: s is System.String, t is System.String
        // True
        // OpTest<T>: s is System.String, t is System.String
        // False
    }
    
    public class TestClass
    {
        public static void OpTest(string s, string t)
        {
            Console.WriteLine($"OpTest: s is {s.GetType()}, t is {t.GetType()}");
            // Uses String's == operator, which compares the values
            Console.WriteLine(s == t);
        }
    
        public static void OpTest<T>(T s, T t) where T : class
        {
            Console.WriteLine($"OpTest<T>: s is {s.GetType()}, t is {t.GetType()}");
            // Uses Object's == operator, which is a reference comparison
            Console.WriteLine(s == t);
        }
    }