bugfix> 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() しかし、それは同様にそれをカットしません。

これはフィドル 私は取り組んでいます。

オブジェクトにデフォルト値が含まれているかどうか、またはオブジェクトが空かどうかを確認する方法はありますか?


編集:多くのネストされたプロパティを持つ新しく初期化されたオブジェクトの場合、それらにデフォルト値が含まれているかどうかを確認する方法は?

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

こちらがフィドル ネストされたオブジェクトの場合。

回答 2 件
  • Equals をオーバーライドすることで目標を達成できます  および GetHashCode 、不変の「デフォルト」インスタンスを作成して保存し、値を比較します。

    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 を実行できます  「デフォルト」オブジェクトを変更します。

  • オブジェクトが等しいかどうかを確認できるJSONシリアル化を使用する1つの方法を次に示します。

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

    出力:

    First Test

    Same thing

    Second Test

    Not same thing

    起こっているのは、デフォルトのオブジェクトをシリアライズしてから、「デフォルトではないオブジェクト」に変更を加え、再度シリアライズして再度比較することです。これは遅くなる可能性があります 文字列を生成しているが、すべてのサブオブジェクトをシリアル化できる限り、これはオブジェクトが「デフォルト」( new から取得したもの)かどうかを比較する最も簡単な方法です。 )または変更されました。

あなたの答え