Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why isn't 0==0?

Activator.CreateInstance(p.PropertyType) == value is false

Given a type T:

public class ODataTestHelper
        {
            public int DataId { get; set; }
            public string DataItem { get; set; }
        }

And a foreach over the properties:

public string BuildQuery<T>(T searchModel,int page, int pageSize)
{
  var type=typeof(T);
  var filters = new List<string>();
  foreach (var p in type.GetProperties())
  {
    var value=p.GetValue(searchModel,null);
    if(value == null || value.ToString().IsNullOrEmpty() || (p.PropertyType.IsValueType && Activator.CreateInstance(p.PropertyType) == value ))
        continue;
     filters.Add(string.Format("{0} eq {1}", p.Name, WrapTypeValue(p.PropertyType, value)));
  }
   if (filters.Any())
        {
            result += "&$filter=" + filters.Aggregate((s1, s2) => s1 + " and ");
        }
        return result;
 }

Given a test method

[TestMethod]
        public void BuildQuery_StringProperty_ItRendersTheFilter()
        {
            const string x = "foo";
            string expected =String.Format( "&$filter={0} eq '{1}'",LinqOp.PropertyOf(() => default(ODataTestHelper).DataItem).Name , x);
            var od = new ODataBinder("http://localhost/");
            var q = od.BuildQuery(new ODataTestHelper { DataItem = x}, 0, 0);
            Assert.IsTrue(q.Contains(expected), string.Format("{0} did not contain {1}", q, expected));

        }

The immediate window confirms that the default coming out is 0 and the value in the instance is 0. It also confirms that p.PropertyType.IsValueType

0 doesn't == the call to Activator.CreateInstance(p.PropertyType) so it doesn't skip the unintiailized DataId. This is the answer for creating a default value per How can I call default(T) with a type? and Create default instance of type but I can't seem to == or .Equals to test for equality?

like image 963
Maslow Avatar asked Feb 17 '23 13:02

Maslow


1 Answers

The simple answer here is that they are different objects. The == operator in this context checks to see if both expressions reference same object. While the value of the two objects may be the same, the objects are not the same object and therefore not equal.

To establish if the two objects have the same value you should use: (<expression 1>).Equals(<expression2) and not <expression 1> == <expression 2>

You may need to override the Equals method to make this work in C# as I see by default the method checks for the same condition as ==. See here.

like image 187
Philip Couling Avatar answered Feb 27 '23 11:02

Philip Couling