简体   繁体   English

C# 比较参考值和值

[英]C# Comparing a reference and a value

I have trouble with this method when passing values to it.将值传递给此方法时,我遇到了麻烦。

Notice: The system using this function is from my perspective a black box and can therefore not be changed.注意:使用此 function 的系统在我看来是一个黑盒子,因此无法更改。

The problem is that passing identical values such as strings, bools, objects etc. to the method will say that they are not equal even though the values are identical.问题是,将相同的值(如字符串、布尔值、对象等)传递给方法会说它们不相等,即使值相同。 I assumed that it is because one is a reference while the other is a value and they therefore "are different".我认为这是因为一个是参考,而另一个是值,因此它们“不同”。

    protected void SetData<T>(ref T field, T value)
        {
            if (!EqualityComparer<T>.Default.Equals(field, value))
            {
                Console.WriteLine("They are NOT equal");
            }
            else
            {
                Console.WriteLine("They are equal");
            }
        }

To test this assumption I made some different unit tests.为了测试这个假设,我做了一些不同的单元测试。

        public bool AreEqual<T>(ref T field, T value)
        {
            return EqualityComparer<T>.Default.Equals(field, value);
        }

    [TestMethod]
    public void IsDirtyString()
    {
        var tc = new Program();
        var field = "Germany";
        var value = "United States";
        var result = tc.AreEqual(ref field, value);
        Assert.IsFalse(result);
    }
    [TestMethod]
    public void IsNotDirtyString()
    {
        var tc = new Program();
        var field = "Nepal";
        var value = "Nepal";
        var result = tc.AreEqual(ref field, value);
        Assert.IsTrue(result);
    }
    [TestMethod]
    public void IsDirtyDouble()
    {
        var tc = new Program();
        var field = 11.2;
        var value = 12.3;
        var result = tc.AreEqual(ref field, value);
        Assert.IsFalse(result);
    }
    [TestMethod]
    public void IsNotDirtyDouble()
    {
        var tc = new Program();
        var field = 12.3;
        var value = 12.3;
        var result = tc.AreEqual(ref field, value);
        Assert.IsTrue(result);
    }
    [TestMethod]
    public void IsDirtyInt()
    {
        var tc = new Program();
        var field = 12;
        var value = 15;
        var result = tc.AreEqual(ref field, value);
        Assert.IsFalse(result);
    }
    [TestMethod]
    public void IsNotDirtyInt()
    {
        var tc = new Program();
        var field = 12;
        var value = 12;
        var result = tc.AreEqual(ref field, value);
        Assert.IsTrue(result);
    }
    [TestMethod]
    public void IsDirtyBool()
    {
        var tc = new Program();
        var field = true;
        var value = false;
        var result = tc.AreEqual(ref field, value);
        Assert.IsFalse(result);
    }
    [TestMethod]
    public void IsNotDirtyBool()
    {
        var tc = new Program();
        var field = true;
        var value = true;
        var result = tc.AreEqual(ref field, value);
        Assert.IsTrue(result);
    }

The result is that the unit tests all pass... as "expected"结果是单元测试都通过了......“预期”

So when I test, it works as intended, but when I connect to the rest of the system and debug so i can see the values of "field" and "value", it does not.因此,当我测试时,它按预期工作,但是当我连接到系统的 rest 并进行调试时,我可以看到“字段”和“值”的值,但它没有。

Has anybody tried something like this before?有没有人尝试过这样的事情?

You are missing the equality comparer.您缺少平等比较器。

As you can see in this example even if equals, the output will be false:正如您在此示例中看到的那样,即使等于,output 也会为假:

class Program
{
    static void Main(string[] args)
    {
        Pizza pizza1 = new Pizza(1);
        Pizza pizza2 = new Pizza(1);
        bool equal = AreEqual(pizza1, pizza2);
        Console.WriteLine(equal);
    }

    public static bool AreEqual<T>(T field, T value)
    {
        return EqualityComparer<T>.Default.Equals(field, value);
    }
}

public class Pizza
{
    public Pizza(int slices)
    {
        Slices = slices;
    }
    public int Slices { get; set; }
}

Output: Output:

False错误的


This way it will work even with custom objects:这样它甚至可以使用自定义对象:

class Program
{
    static void Main(string[] args)
    {
        Pizza pizza1 = new Pizza(1);
        Pizza pizza2 = new Pizza(1);
        bool equal = AreEqual(pizza1, pizza2, new PizzaComparer());
        Console.WriteLine(equal);
    }

    public static bool AreEqual<T>(T field, T value, IEqualityComparer<T> equalityComparer)
    {
        return equalityComparer.Equals(field, value);
    }
}

public class Pizza
{
    public Pizza(int slices)
    {
        Slices = slices;
    }
    public int Slices { get; set; }
}

public class PizzaComparer : IEqualityComparer<Pizza>
{
    public bool Equals(Pizza pizza1, Pizza pizza2)
    {
        return pizza1.Slices == pizza2.Slices;
    }

    public int GetHashCode(Pizza pizza)
    {
        return pizza.Slices.GetHashCode();
    }
}

Output: Output:

True真的

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM