C#char返回方法和对象返回方法

时间:2017-01-29 15:41:24

标签: c# object methods char

我在解决挑战测试时遇到了一个小问题,我正在比较

的输出
private object PopS() {
   return stack.Pop();
}

private object DequeueQ() {
   return queue.Dequeue();
}

为回文词。

Statment:

if(PopS() != DequeueQ()) isPalindrome = false;

我在这个IF声明上做了断点,作为输入回文词“aaaaa”提供,但是尽管Locals窗口显示Pop()返回97'a'而DequeueQ()返回97'a',但是认为两者都不等于”

当我将方法转换从对象更改为char时,它起作用了。本地人的输出是相同的。

有人能解释一下这种行为吗?试着理解为什么来自“对象”演员的两个相同的回报不相等而且来自“char”演员的2个相同的回报是相等的。

非常感谢, 迈克尔。

2 个答案:

答案 0 :(得分:1)

这被称为“拳击”。

如您所知,当==运算符用于没有重载==的引用类型时,它会比较引用是否相同。另一方面,当与值类型一起使用时,它会比较值。

这两个char最初是值类型,这就是为什么更改方法以返回char会使其工作。 'a''a'的值相等。

但方法的返回类型都是objectobject是引用类型。因此,在运行时,两个char需要成为引用类型。这被称为拳击。每个char都装箱,因此有两个单独的对象,都包含值'a'。但由于它们是引用类型,==检查它们是否是同一个对象,它们显然不是。因此,==评估为false

答案 1 :(得分:0)

此类适用于类和Equals(object o)(覆盖operator ==)方法。字符的定义如下:

public class char : object
{
    private uint value;

    //some more implementation

    override bool Equals(object o)
    {
        //code simplified - no try-catches etc.
        return this.value.Equals((uint) o);
    }
}

现在,当您尝试比较object类型的对象时,它们没有覆盖此Equals方法并使用默认方法。由于对象是默认的引用类型,因此它们试图比较引用。

有关MSDN的更多详情。

同样MSDN - Class and struct differences会为您提供更多信息。

您的代码有什么作用?

一边是'a',另一边是'a'。它将创建每个(对象)的新实例,如:

char obj1 = 'a';
char obj2 = 'a';

如果将它们作为字符进行比较,您将获得真正的价值:

obj1.Equals(obj2); //true

但是如果你将它们抛给对象,Equals的内部实现将检查内存(PC的物理内存)并查看obj1的实例和obj2的实例。如果他们没有找到两个相同的位置(相同的内存地址 - 内存中的相同单元格,它将返回false)

((object)obj1).Equals(obj2); // false
((object)obj1).Equals((object)obj2); // false
(obj1).Equals((object)obj2); // false

可以通过在调用Equals方法之前转换变量来避免这种情况。

((char)(object)obj1).Equals(obj2); // true
((char)(object)obj1).Equals((char)(object)obj2); // true
(obj1).Equals((char)(object)obj2); // true

如何使用引用相等?

public class MyClass
{
    public char Val { get; set; }
}

MyClass obj1 = new MyClass() { Val = 'a' };
MyClass obj2 = obj1;
obj1.Equals(obj2); // true

**注意:**我没有像@Sweeper那样使用术语“拳击”。

拳击意味着对象被转换为不同的对象,并获得与作为其他对象处理相关的不同行为。 (它与OOP术语多态性密切相关)。