Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check if an object has default values in C#

Tags:

c#

I have an object that I want to check whether it contains default values or not, in the below code but that doesn't cut it.

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

I have also used Object.ReferenceEquals() but that doesn't cut it as well.

This is the fiddle I am working on.

Is there a way to check whether an object contains default values, or if the object is empty?


Edit: In case of an newly initialized object with many nested properties, how to check whether they contain a default value or not?

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

}

Here is the fiddle in the case of nested objects.

like image 525
Kunal Mukherjee Avatar asked Nov 20 '25 15:11

Kunal Mukherjee


2 Answers

You can achieve your goal by overriding Equals and GetHashCode, creating and saving an immutable "default" instance, and comparing the value to it:

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

Now you can check if the instance is equal to a newly created one by calling

if (MyClass.DefaultInstance.Equals(instanceToCheck)) {
    ... // All defaults
}

You can change what it means for an instance to be "default" by altering DefaultInstance object.

Note: this trick works well only with immutable MyClass. Otherwise some code could perform MyClass.DefaultInstance.Value = 20 and change the "default" object.

like image 189
Sergey Kalinichenko Avatar answered Nov 22 '25 06:11

Sergey Kalinichenko


Here is one method using JSON serialization that allows you to check if the objects are equal or not:

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

Output:

First Test

Same thing

Second Test

Not same thing

What is happening is that you serialize the default object and then you make changes to the "not default object", re-serialize and compare again. This can be slow because you are generating strings, but as long as all the sub-objects can be serialized this will be the simplest way to compare if an object is "default" (what you get from new) or has been modified.

like image 42
Ron Beyer Avatar answered Nov 22 '25 06:11

Ron Beyer



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!