C # Сравнение ссылки и значения - PullRequest
0 голосов
/ 30 сентября 2019

У меня проблемы с этим методом при передаче ему значений.

Примечание: система, использующая эту функцию, с моей точки зрения, является черным ящиком и поэтому не может быть изменена.

Проблема состоит в том, что передача идентичных значений, таких как строки, bools, объекты и т. Д., Методу будет означать, что они не равны, даже если значения идентичны. Я предположил, что это потому, что один является ссылкой, а другой является значением, и поэтому они «разные».

    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");
            }
        }

Чтобы проверить это предположение, я провел несколько разных модульных тестов.

        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);
    }

В результате все модульные тесты прошли ... как и ожидалось"

Так что, когда я тестирую, он работает как задумано, но когда я подключаюсь к остальной части системы и отлаживаю, чтобы я мог видеть значения" field "и" value ", это не так.

Кто-нибудь пробовал что-то подобное раньше?

1 Ответ

0 голосов
/ 30 сентября 2019

Вам не хватает средства сравнения равенства.

Как видно из этого примера, даже если он равен, вывод будет ложным:

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; }
}

Вывод:

False


Таким образом, он будет работать даже с пользовательскими объектами:

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();
    }
}

Вывод:

True

...