如何检查对象在C#中是否具有默认值

时间:2018-05-19 15:04:33

标签: c#

我有一个对象,我想检查它是否包含默认值,在下面的代码中,但不会删除它。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
           MyClass obj1 = new MyClass();
           MyClass obj2 = null;

           if(obj1 == new MyClass())
            Console.WriteLine("Initialized");

           if(Object.ReferenceEquals(obj1, new MyClass()))
              Console.WriteLine("Initialized");

        }
    }
}

public class MyClass
{
    public int Value {get; set; }

    public MyClass()
    {
        this.Value = 10;
    }
}

我也使用了Object.ReferenceEquals(),但这并没有削减它。

这是我正在处理的 fiddle

有没有办法检查某个对象是否包含默认值,或者该对象是否为空?

编辑:如果新初始化的对象具有许多嵌套属性,如何检查它们是否包含默认值?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;

namespace Rextester
{
    public class Program
    {
        public static void Main(string[] args)
        {
           MyClass obj1 = new MyClass();
           MyClass obj2 = null;

           if(obj1 == new MyClass())
            Console.WriteLine("Initialized");

           if(Object.ReferenceEquals(obj1, new MyClass()))
              Console.WriteLine("Initialized");


        }
    }
}

public class MyClass
{
    public int Value {get; set; }

    public MyNestedClass MyProperty { get; set; }

    public MyClass()
    {
        this.Value = 10;
        this.MyProperty = new MyNestedClass();
    }
}

public class MyNestedClass
{
    public string SomeStringProperty { get; set; }

    public MyNestedClass()
    {
        this.SomeStringProperty = "Some string";
    }

}

在嵌套对象的情况下,这是fiddle

2 个答案:

答案 0 :(得分:4)

您可以通过覆盖EqualsGetHashCode来实现目标,创建并保存不可变的"默认"实例,并将值与它进行比较:

public class MyClass {
    public static readonly MyClass DefaultInstance = new MyClass();
    public int Value { get; set; }
    public MyClass() {
        this.Value = 10;
    }
    public override int GetHashCode() {
        return Value.GetHashCode();
    }
    public override bool Equals(Object obj) {
        if (obj == this) return true;
        var other = obj as MyClass;
        return other?.Value == this.Value;
    }
}

现在,您可以通过调用

来检查实例是否等于新创建的实例
if (MyClass.DefaultInstance.Equals(instanceToCheck)) {
    ... // All defaults
}

您可以更改实例的含义"默认"通过改变DefaultInstance对象。

注意:此技巧仅适用于不可变MyClass。否则,某些代码可以执行MyClass.DefaultInstance.Value = 20并更改"默认"对象

答案 1 :(得分:2)

这是一种使用JSON序列化的方法,允许您检查对象是否相等:

DotNetFiddle

using System;
using Newtonsoft.Json;

public class Program
{
    public static void Main()
    {
        var defaultObj = new MasterObject();
        var notDefaultObject = new MasterObject();

        var defaultJson = JsonConvert.SerializeObject(defaultObj);
        var notDefaultJson = JsonConvert.SerializeObject(notDefaultObject);

        Console.WriteLine("First Test");
        if (defaultJson == notDefaultJson) 
            Console.WriteLine("Same thing");
        else
            Console.WriteLine("Not same thing");

        notDefaultObject.Sub1.SomeObject.SomeOtherValue = "Not a default Value";

        notDefaultJson = JsonConvert.SerializeObject(notDefaultObject);

        Console.WriteLine("Second Test");
        if (defaultJson == notDefaultJson) 
            Console.WriteLine("Same thing");
        else
            Console.WriteLine("Not same thing");

    }

}


public class MasterObject 
{
    public SubObject1 Sub1 { get; set; }
    public SubObject2 Sub2 { get; set; }
    public string SomeString { get; set; }

    public MasterObject()
    {
        Sub1 = new SubObject1();
        Sub2 = new SubObject2();
        SomeString = "Some Default String";
    }
}

public class SubObject1 
{
    public string SomeValue { get; set; }
    public SubObject2 SomeObject { get; set; }

    public SubObject1()
    {
        SomeObject = new SubObject2();
        SomeValue = "Some other Default String";
    }
}

public class SubObject2
{
    public string SomeOtherValue { get; set; }

    public SubObject2()
    {
        SomeOtherValue = "Some default";
    }
}

输出:

  

第一次测试

     

同样的事情

     

第二次测试

     

不一样

发生的事情是您序列化默认对象,然后更改“非默认对象”,重新序列化并再次进行比较。 这可能很慢,因为您正在生成字符串,但只要所有子对象都可以序列化,这将是比较对象是否为“默认”的最简单方法(您从{获得的内容) {1}})或已被修改。