【问题标题】:Why parameter of Object.Equals is not 'in' (input)?为什么 Object.Equals 的参数不是“in”(输入)?
【发布时间】:2019-06-25 11:38:13
【问题描述】:

以下(不正确/危险)代码

class EvilClass
{
    protected int x;

    public EvilClass(int x)
    {
        this.x = x;
    }

    public override bool Equals(Object obj)
    {
        if ((obj == null) || !this.GetType().Equals(obj.GetType()))
        {
            return false;
        }
        else
        {
            EvilClass p = (EvilClass)obj;
            p.x = 42;
            return (x == p.x);
        }
    }

    public override int GetHashCode()
    {
        return (x << 2);
    }

    public override string ToString()
    {
        return String.Format("EvilClass({0})", x);
    }
}

void Main()
{
    var e1 = new EvilClass(1);
    var e2 = new EvilClass(2);

    var equals = e1.Equals(e2);
    Console.WriteLine("{0}", e1.ToString());
    Console.WriteLine("{0}", e2.ToString());
}

输出:

EvilClass(1)
EvilClass(42)

如您所见,调用e1.Equals(e2) 修改e2。如果我们将参数标记为 in 编译器将不允许我们修改它。

Object.Equals() 不应该改变它的参数 - 那么为什么参数不是 in (输入)参数?

【问题讨论】:

  • 最近添加了此上下文中的 in 关键字作为传递值类型的优化。实践中的结构。知道通过引用传递的结构不会发生变异,因此不必将副作用传递回调用者,可以使代码更高效。它并没有使 C# 成为更好的语言。 Object.Equals() 的作者使用了更好的语言,不需要帮助来弄清楚 ref/out 的作用。

标签: c#


【解决方案1】:

最明显的原因是 in 是在 C# 7.2 中引入的,而 object.Equals 从 .net 的第一个版本就已经存在。

另一个原因是它实际上不会改变任何东西。 in 防止改变引用,而不是实际对象。如果你试试这个:

public bool Equals2(in Object obj)
{
    if ((obj == null) || !this.GetType().Equals(obj.GetType()))
    {
        return false;
    }
    else
    {
        EvilClass p = (EvilClass)obj;
        p.x = 42;
        return (x == p.x);
    }
}

那么输出仍然是:

EvilClass(1)
EvilClass(42)

【讨论】:

    猜你喜欢
    • 2020-09-11
    • 2012-04-03
    • 2012-06-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多