উত্তর:
বাস্তবায়ন IEquatable<T>(অগ্রাহ্য উত্তরাধিকারসূত্রে সাথে সাধারণত Object.Equalsএবং Object.GetHashCodeআপনার সমস্ত কাস্টম ধরনের পদ্ধতি)। সম্মিলিত প্রকারের ক্ষেত্রে অন্তর্ভুক্ত প্রকারের মধ্যে অন্তর্ভুক্ত প্রকারের Equalsপদ্ধতিটি আহ্বান করুন । অন্তর্ভুক্ত সংগ্রহের জন্য, SequenceEqualএক্সটেনশন পদ্ধতিটি ব্যবহার করুন , যা অভ্যন্তরীণভাবে IEquatable<T>.Equalsবা Object.Equalsপ্রতিটি উপাদানকে কল করে। এই পদ্ধতির স্পষ্টতই আপনাকে আপনার ধরণের সংজ্ঞাগুলি প্রসারিত করতে হবে তবে এর ফলাফলগুলি সিরিয়ালকরণের সাথে জড়িত যে কোনও জেনেরিক সমাধানের চেয়ে দ্রুত।
সম্পাদনা করুন : নীচে বাসা বাঁধানোর তিনটি স্তর সহ এখানে একটি স্বতন্ত্র উদাহরণ।
মান ধরণের জন্য, আপনি সাধারণত তাদের Equalsপদ্ধতিটি কল করতে পারেন । এমনকি ক্ষেত্র বা বৈশিষ্ট্যগুলি কখনই স্পষ্টভাবে বরাদ্দ না করা থাকলেও তাদের ডিফল্ট মান থাকতে পারে।
রেফারেন্স ধরণের জন্য, আপনাকে প্রথমে কল করা উচিত ReferenceEquals, যা রেফারেন্সের সমতার জন্য পরীক্ষা করে - এটি যখন আপনি একই অবজেক্টটি উল্লেখ করছেন তখন এটি দক্ষতা বৃদ্ধির কাজ করবে। এটি উভয় উল্লেখ বাতিল হয়ে যায় এমন ক্ষেত্রেও পরিচালনা করবে। যদি সেই চেকটি ব্যর্থ হয় তবে নিশ্চিত করুন যে আপনার উদাহরণের ক্ষেত্র বা সম্পত্তি নাল নয় (এড়াতে NullReferenceException) এবং এর Equalsপদ্ধতিটি কল করুন । যেহেতু আমাদের সদস্যরা যথাযথভাবে টাইপ করা হয়েছে, IEquatable<T>.Equalsওভাররাইড Object.Equalsপদ্ধতিটি (যাঁর প্রয়োগের প্রকারের ফলে প্রান্তিকভাবে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে ধীরে বৃদ্ধি পাবে)
আপনি যখন ওভাররাইড করবেন তখন আপনারও ওভাররাইড হওয়া Object.Equalsআশা করা যায় Object.GetHashCode; সংক্ষিপ্ততার জন্য আমি নীচে এটি করিনি।
public class Person : IEquatable<Person>
{
public int Age { get; set; }
public string FirstName { get; set; }
public Address Address { get; set; }
public override bool Equals(object obj)
{
return this.Equals(obj as Person);
}
public bool Equals(Person other)
{
if (other == null)
return false;
return this.Age.Equals(other.Age) &&
(
object.ReferenceEquals(this.FirstName, other.FirstName) ||
this.FirstName != null &&
this.FirstName.Equals(other.FirstName)
) &&
(
object.ReferenceEquals(this.Address, other.Address) ||
this.Address != null &&
this.Address.Equals(other.Address)
);
}
}
public class Address : IEquatable<Address>
{
public int HouseNo { get; set; }
public string Street { get; set; }
public City City { get; set; }
public override bool Equals(object obj)
{
return this.Equals(obj as Address);
}
public bool Equals(Address other)
{
if (other == null)
return false;
return this.HouseNo.Equals(other.HouseNo) &&
(
object.ReferenceEquals(this.Street, other.Street) ||
this.Street != null &&
this.Street.Equals(other.Street)
) &&
(
object.ReferenceEquals(this.City, other.City) ||
this.City != null &&
this.City.Equals(other.City)
);
}
}
public class City : IEquatable<City>
{
public string Name { get; set; }
public override bool Equals(object obj)
{
return this.Equals(obj as City);
}
public bool Equals(City other)
{
if (other == null)
return false;
return
object.ReferenceEquals(this.Name, other.Name) ||
this.Name != null &&
this.Name.Equals(other.Name);
}
}
আপডেট : এই উত্তরটি বেশ কয়েক বছর আগে লেখা হয়েছিল। তার পর থেকে, আমি এই IEquality<T>জাতীয় দৃশ্যের জন্য পরিবর্তনীয় ধরণের জন্য প্রয়োগ থেকে দূরে ঝুঁকতে শুরু করেছি । সমতা দুটি ধারণা আছে: পরিচয় এবং সমতা । একটি স্মৃতি প্রতিনিধিত্ব স্তরে, এগুলিকে "রেফারেন্স সমতা" এবং "মান সমতা" ( সমতা তুলনা দেখুন ) হিসাবে জনপ্রিয় হিসাবে চিহ্নিত করা হয় । তবে একই পার্থক্যটি একটি ডোমেন স্তরেও প্রয়োগ করতে পারে। মনে করুন যে আপনার Personশ্রেণীর একটি PersonIdসম্পত্তি রয়েছে, স্বতন্ত্র বাস্তব-ব্যক্তির প্রতি অনন্য। একই PersonIdতবে পৃথক Ageমান সহ দুটি বস্তুকে সমান বা পৃথক বিবেচনা করা উচিত? উপরের উত্তরটি ধরে নিয়েছে যে একটি সমতার পরে। তবে এর অনেকগুলি ব্যবহার রয়েছেIEquality<T>ইন্টারফেস, যেমন সংগ্রহ যেমন, ধরে নেওয়া হয় যে এই জাতীয় বাস্তবায়ন পরিচয়ের জন্য সরবরাহ করে । উদাহরণস্বরূপ, আপনি যদি জনগোষ্ঠী স্থাপন করছেন HashSet<T>, আপনি সাধারণত TryGetValue(T,T)কলটি এমন বিদ্যমান উপাদানগুলি ফিরিয়ে আনার প্রত্যাশা করবেন যা কেবলমাত্র আপনার যুক্তির পরিচয় ভাগ করে নেবে, অগত্যা প্রয়োজনীয় উপাদানগুলির সমপরিমাণ একই নয় contents এই ধারণাটি নোটগুলি দ্বারা প্রয়োগ করা হয় GetHashCode:
সাধারণত, পরিবর্তনীয় রেফারেন্স প্রকারের জন্য, আপনার
GetHashCode()কেবলমাত্র ওভাররাইড করা উচিত যদি:
- আপনি এমন ক্ষেত্রগুলি থেকে হ্যাশ কোডটি গণনা করতে পারবেন যা পরিবর্তনীয় নয়; অথবা
- আপনি নিশ্চিত করতে পারেন যে কোনও হ'ল কোডের উপর নির্ভর করে এমন কোনও সংস্থায় বস্তুটি থাকা অবস্থায় কোনও মিউটয়েবল অবজেক্টের হ্যাশ কোডটি পরিবর্তন হয় না।
partial- হ্যাঁ, আপনি নিজের Equalsপদ্ধতিতে যুক্ত আংশিক শ্রেণির ঘোষণার মাধ্যমে তাদের পদ্ধতিটি প্রয়োগ করতে পারেন যা স্বয়ংক্রিয়ভাবে উত্পন্ন উত্পন্ন ক্ষেত্র / বৈশিষ্ট্যগুলি উল্লেখ করে এক.
Enumerable.SequenceEqualঅ্যারে তে পদ্ধতি: this.Addresses.SequenceEqual(other.Addresses)। শ্রেণিটি ইন্টারফেস প্রয়োগ করে Address.Equals, এটি প্রতিটি জোড়টিকে সম্পর্কিত ঠিকানাগুলির জন্য অভ্যন্তরীণভাবে কল করবে call AddressIEquatable<Address>
উভয় অবজেক্টকে সিরিয়াল করুন এবং ফলাফলযুক্ত স্ট্রিংগুলি তুলনা করুন
+1এটি কেবল কারণ এটি আমি কোনও মান-ভিত্তিক সাম্যতা তুলনা এইভাবে করার কথা ভাবি নি। এটি দুর্দান্ত এবং সাধারণ। এই কোড সহ কিছু মানদণ্ড দেখতে ঝরঝরে হতে চাই।
আপনি এই সমস্যাটি সমাধানের জন্য এক্সটেনশন পদ্ধতি, পুনরাবৃত্তি ব্যবহার করতে পারেন:
public static bool DeepCompare(this object obj, object another)
{
if (ReferenceEquals(obj, another)) return true;
if ((obj == null) || (another == null)) return false;
//Compare two object's class, return false if they are difference
if (obj.GetType() != another.GetType()) return false;
var result = true;
//Get all properties of obj
//And compare each other
foreach (var property in obj.GetType().GetProperties())
{
var objValue = property.GetValue(obj);
var anotherValue = property.GetValue(another);
if (!objValue.Equals(anotherValue)) result = false;
}
return result;
}
public static bool CompareEx(this object obj, object another)
{
if (ReferenceEquals(obj, another)) return true;
if ((obj == null) || (another == null)) return false;
if (obj.GetType() != another.GetType()) return false;
//properties: int, double, DateTime, etc, not class
if (!obj.GetType().IsClass) return obj.Equals(another);
var result = true;
foreach (var property in obj.GetType().GetProperties())
{
var objValue = property.GetValue(obj);
var anotherValue = property.GetValue(another);
//Recursion
if (!objValue.DeepCompare(anotherValue)) result = false;
}
return result;
}
বা জেসন ব্যবহার করে তুলনা করুন (যদি বস্তুটি খুব জটিল হয়) আপনি নিউটনসফট.জসন ব্যবহার করতে পারেন:
public static bool JsonCompare(this object obj, object another)
{
if (ReferenceEquals(obj, another)) return true;
if ((obj == null) || (another == null)) return false;
if (obj.GetType() != another.GetType()) return false;
var objJson = JsonConvert.SerializeObject(obj);
var anotherJson = JsonConvert.SerializeObject(another);
return objJson == anotherJson;
}
DeepCompareকেবল CompareExপুনরাবৃত্তি কল করার পরিবর্তে ব্যবহার করার কোনও কারণ আছে কি ?
resultকরা return falseএটি আরও দক্ষ করে তুলবে।
আপনি যদি আইক্যাটেবল বাস্তবায়ন করতে না চান, আপনি সর্বদা সমস্ত বৈশিষ্ট্যের তুলনা করতে প্রতিবিম্ব ব্যবহার করতে পারেন: - যদি তারা মান ধরণের হয় তবে কেবল তাদের সাথে তুলনা করুন - যদি তারা রেফারেন্স টাইপ হয় তবে এর "অভ্যন্তরীণ" বৈশিষ্ট্যগুলি তুলনা করার জন্য ফাংশনটিকে পুনরাবৃত্তভাবে কল করুন ।
আমি পারফরম্যান্স নিয়ে ভাবছি না, সরলতার কথা ভাবছি। এটি নির্ভর করে তবে আপনার সামগ্রীর সঠিক নকশার উপর। এটি আপনার বস্তুর আকারের উপর নির্ভর করে জটিল হয়ে উঠতে পারে (উদাহরণস্বরূপ যদি বৈশিষ্ট্যের মধ্যে চক্রীয় নির্ভরতা থাকে)। তবে এখানে বেশ কয়েকটি সমাধান রয়েছে যা আপনি এটির মতো ব্যবহার করতে পারেন:
আর একটি বিকল্প হ'ল পাঠ্য হিসাবে বস্তুকে সিরিয়ালাইজ করা, উদাহরণস্বরূপ JSON.NET ব্যবহার করা, এবং সিরিয়ালাইজেশন ফলাফলের সাথে তুলনা করা। (JSON.NET বৈশিষ্ট্যের মধ্যে চক্রীয় নির্ভরতা পরিচালনা করতে পারে)।
আমি জানি না দ্রুততম দ্বারা আপনি এটি বাস্তবায়নের দ্রুততম উপায় বা একটি কোড যা দ্রুত চলে mean আপনার যদি প্রয়োজন হয় তা জানার আগে আপনার অনুকূলিত হওয়া উচিত নয়। অকালীন অপটিমাইজেশন হ'ল সমস্ত অশুভের মূল
IEquatable<T>বাস্তবায়ন অকাল অনুকূলকরণের ক্ষেত্রে যোগ্যতা অর্জন করে। প্রতিবিম্ব মারাত্মকভাবে ধীর হবে। Equalsকাস্টম মান ধরণের জন্য ডিফল্ট বাস্তবায়ন প্রতিবিম্ব ব্যবহার করে; মাইক্রোসফ্ট নিজেরাই এটিকে কার্য সম্পাদনের জন্য ওভাররাইড করার পরামর্শ দেয়: " Equalsপদ্ধতির কার্যকারিতা উন্নত করতে কোনও নির্দিষ্ট ধরণের জন্য পদ্ধতির ওভাররাইড করুন এবং এই ধরণের সাম্যের ধারণাটি আরও ঘনিষ্ঠভাবে উপস্থাপন করুন।"
উভয় অবজেক্টকে সিরিয়াল করুন এবং ফলাফলযুক্ত স্ট্রিংগুলি @ জোয়েলফ্যানের সাথে তুলনা করুন
এটি করার জন্য, এর মতো একটি স্ট্যাটিক ক্লাস তৈরি করুন এবং সমস্ত বস্তু প্রসারিত করতে এক্সটেনশনগুলি ব্যবহার করুন (যাতে আপনি কোনও ধরণের অবজেক্ট, সংগ্রহ ইত্যাদি পদ্ধতিতে পাস করতে পারেন)
using System;
using System.IO;
using System.Runtime.Serialization.Json;
using System.Text;
public static class MySerializer
{
public static string Serialize(this object obj)
{
var serializer = new DataContractJsonSerializer(obj.GetType());
using (var ms = new MemoryStream())
{
serializer.WriteObject(ms, obj);
return Encoding.Default.GetString(ms.ToArray());
}
}
}
আপনি অন্য কোনও ফাইলে এই স্থিত শ্রেণিকে একবার উল্লেখ করলে আপনি এটি করতে পারেন:
Person p = new Person { Firstname = "Jason", LastName = "Argonauts" };
Person p2 = new Person { Firstname = "Jason", LastName = "Argonaut" };
//assuming you have already created a class person!
string personString = p.Serialize();
string person2String = p2.Serialize();
এখন আপনি কেবল ব্যবহার করতে পারেন .একটি তুলনা করার জন্য যোগ্যতা। আমি বস্তুগুলি খুব সংগ্রহে রয়েছে কিনা তা যাচাই করার জন্য এটি ব্যবহার করি। এটি সত্যিই ভাল কাজ করে।
CultrureInfo। এটি কেবল তখনই কাজ করবে যদি অভ্যন্তরীণ ডেটা বেশিরভাগ স্ট্রিং এবং পূর্ণসংখ্যা হয়। অন্যথায় এটি একটি বিপর্যয় হবে।
আমি ধরে নেব আপনি আক্ষরিকভাবে একই জিনিসগুলিকে উল্লেখ করছেন না
Object1 == Object2
আপনি দুজনের মধ্যে একটি স্মৃতি তুলনা করতে ভাবতে পারেন
memcmp(Object1, Object2, sizeof(Object.GetType())
তবে এটি সি # :) তেও আসল কোড নয়। যেহেতু আপনার সমস্ত ডেটা সম্ভবত স্তূপে তৈরি করা হয়েছে, স্মৃতিটি সংক্ষিপ্ত নয় এবং আপনি কেবল দুটি বস্তুর সমতার তুলনা করতে পারবেন না অজ্ঞেয় পদ্ধতিতে। আপনাকে প্রতিটি মানকে একবারে একটি কাস্টম পদ্ধতিতে তুলনা করতে হবে।
IEquatable<T>আপনার শ্রেণিতে ইন্টারফেস যুক্ত করার বিষয়টি বিবেচনা করুন এবং Equalsআপনার ধরণের জন্য একটি পছন্দসই পদ্ধতিটি নির্ধারণ করুন। তারপরে, সেই পদ্ধতিতে, প্রতিটি মান ম্যানুয়াল পরীক্ষা করে। যোগ IEquatable<T>আবার ঘিরা ধরনের যদি আপনি এবং প্রক্রিয়ার পুনরাবৃত্তি করতে পারেন।
class Foo : IEquatable<Foo>
{
public bool Equals(Foo other)
{
/* check all the values */
return false;
}
}
উভয় বস্তু সিরিয়াল করুন, তারপরে হ্যাশ কোড গণনা করুন, তারপরে তুলনা করুন।
বস্তুর তুলনা করার জন্য আমি এটি নীচের ফাংশনটি পেয়েছি।
static bool Compare<T>(T Object1, T object2)
{
//Get the type of the object
Type type = typeof(T);
//return false if any of the object is false
if (object.Equals(Object1, default(T)) || object.Equals(object2, default(T)))
return false;
//Loop through each properties inside class and get values for the property from both the objects and compare
foreach (System.Reflection.PropertyInfo property in type.GetProperties())
{
if (property.Name != "ExtensionData")
{
string Object1Value = string.Empty;
string Object2Value = string.Empty;
if (type.GetProperty(property.Name).GetValue(Object1, null) != null)
Object1Value = type.GetProperty(property.Name).GetValue(Object1, null).ToString();
if (type.GetProperty(property.Name).GetValue(object2, null) != null)
Object2Value = type.GetProperty(property.Name).GetValue(object2, null).ToString();
if (Object1Value.Trim() != Object2Value.Trim())
{
return false;
}
}
}
return true;
}
আমি এটি ব্যবহার করছি এবং এটি আমার পক্ষে ভাল কাজ করছে।
ifঅর্থ Compare(null, null) == falseযা আমি প্রত্যাশা করি না।
ইতিমধ্যে এখানে দেওয়া কয়েকটি উত্তরগুলির ভিত্তিতে আমি বেশিরভাগই জোয়েলফানের উত্তরটি ফিরে আসার সিদ্ধান্ত নিয়েছি । আমি এক্সটেনশন পদ্ধতিগুলি পছন্দ করি এবং এগুলি আমার জন্য দুর্দান্ত কাজ করে যখন অন্য কোনও সমাধান আমার জটিল শ্রেণীর তুলনা করার জন্য তাদের ব্যবহার করে না।
using System.IO;
using System.Xml.Serialization;
static class ObjectHelpers
{
public static string SerializeObject<T>(this T toSerialize)
{
XmlSerializer xmlSerializer = new XmlSerializer(toSerialize.GetType());
using (StringWriter textWriter = new StringWriter())
{
xmlSerializer.Serialize(textWriter, toSerialize);
return textWriter.ToString();
}
}
public static bool EqualTo(this object obj, object toCompare)
{
if (obj.SerializeObject() == toCompare.SerializeObject())
return true;
else
return false;
}
public static bool IsBlank<T>(this T obj) where T: new()
{
T blank = new T();
T newObj = ((T)obj);
if (newObj.SerializeObject() == blank.SerializeObject())
return true;
else
return false;
}
}
if (record.IsBlank())
throw new Exception("Record found is blank.");
if (record.EqualTo(new record()))
throw new Exception("Record found is blank.");
আমি বলতে চাই যে:
Object1.Equals(Object2)
আপনি যা খুঁজছেন তা হবে। আপনি যদি বস্তুগুলি একইরকম কিনা তা আপনি যদি সন্ধান করছেন তবে এটিই আপনি জিজ্ঞাসা করছেন বলে মনে হচ্ছে।
যদি আপনি দেখতে চান যে সমস্ত শিশু অবজেক্ট একইরূপে রয়েছে, তবে সেটিকে Equals()পদ্ধতিটি দিয়ে একটি লুপের মাধ্যমে চালান ।
public class GetObjectsComparison
{
public object FirstObject, SecondObject;
public BindingFlags BindingFlagsConditions= BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
}
public struct SetObjectsComparison
{
public FieldInfo SecondObjectFieldInfo;
public dynamic FirstObjectFieldInfoValue, SecondObjectFieldInfoValue;
public bool ErrorFound;
public GetObjectsComparison GetObjectsComparison;
}
private static bool ObjectsComparison(GetObjectsComparison GetObjectsComparison)
{
GetObjectsComparison FunctionGet = GetObjectsComparison;
SetObjectsComparison FunctionSet = new SetObjectsComparison();
if (FunctionSet.ErrorFound==false)
foreach (FieldInfo FirstObjectFieldInfo in FunctionGet.FirstObject.GetType().GetFields(FunctionGet.BindingFlagsConditions))
{
FunctionSet.SecondObjectFieldInfo =
FunctionGet.SecondObject.GetType().GetField(FirstObjectFieldInfo.Name, FunctionGet.BindingFlagsConditions);
FunctionSet.FirstObjectFieldInfoValue = FirstObjectFieldInfo.GetValue(FunctionGet.FirstObject);
FunctionSet.SecondObjectFieldInfoValue = FunctionSet.SecondObjectFieldInfo.GetValue(FunctionGet.SecondObject);
if (FirstObjectFieldInfo.FieldType.IsNested)
{
FunctionSet.GetObjectsComparison =
new GetObjectsComparison()
{
FirstObject = FunctionSet.FirstObjectFieldInfoValue
,
SecondObject = FunctionSet.SecondObjectFieldInfoValue
};
if (!ObjectsComparison(FunctionSet.GetObjectsComparison))
{
FunctionSet.ErrorFound = true;
break;
}
}
else if (FunctionSet.FirstObjectFieldInfoValue != FunctionSet.SecondObjectFieldInfoValue)
{
FunctionSet.ErrorFound = true;
break;
}
}
return !FunctionSet.ErrorFound;
}
এটি করার একটি উপায় হ'ল Equals()জড়িত প্রতিটি প্রকারের উপর ওভাররাইড করা। উদাহরণস্বরূপ, আপনার শীর্ষ স্তরের অবজেক্টটি সমস্ত 5 শিশু অবজেক্টের পদ্ধতিতে Equals()কল করতে ওভাররাইড করবে Equals()। এই বিষয়গুলিকে সমস্তগুলি Equals()পাশাপাশি ওভাররাইড করা উচিত , তারা ধরে নিচ্ছে যে তারা কাস্টম অবজেক্টস এবং তাই যতক্ষণ না পুরো স্তরক্রমকে কেবল শীর্ষ স্তরের বস্তুগুলিতে সাম্যতা পরীক্ষা করে পরীক্ষা করা যায়।
IEquatable<T>ইন্টারফেস ব্যবহার করুন যার একটি পদ্ধতি রয়েছে Equals।
জোনাথনের উদাহরণের জন্য ধন্যবাদ। আমি এটিকে সমস্ত ক্ষেত্রে (অ্যারে, তালিকা, অভিধান, আদিম ধরণের) প্রসারিত করেছি।
এটি সিরিয়ালাইজেশন ব্যতীত তুলনা এবং তুলনামূলক অবজেক্টগুলির জন্য কোনও ইন্টারফেসের প্রয়োগের প্রয়োজন হয় না।
/// <summary>Returns description of difference or empty value if equal</summary>
public static string Compare(object obj1, object obj2, string path = "")
{
string path1 = string.IsNullOrEmpty(path) ? "" : path + ": ";
if (obj1 == null && obj2 != null)
return path1 + "null != not null";
else if (obj2 == null && obj1 != null)
return path1 + "not null != null";
else if (obj1 == null && obj2 == null)
return null;
if (!obj1.GetType().Equals(obj2.GetType()))
return "different types: " + obj1.GetType() + " and " + obj2.GetType();
Type type = obj1.GetType();
if (path == "")
path = type.Name;
if (type.IsPrimitive || typeof(string).Equals(type))
{
if (!obj1.Equals(obj2))
return path1 + "'" + obj1 + "' != '" + obj2 + "'";
return null;
}
if (type.IsArray)
{
Array first = obj1 as Array;
Array second = obj2 as Array;
if (first.Length != second.Length)
return path1 + "array size differs (" + first.Length + " vs " + second.Length + ")";
var en = first.GetEnumerator();
int i = 0;
while (en.MoveNext())
{
string res = Compare(en.Current, second.GetValue(i), path);
if (res != null)
return res + " (Index " + i + ")";
i++;
}
}
else if (typeof(System.Collections.IEnumerable).IsAssignableFrom(type))
{
System.Collections.IEnumerable first = obj1 as System.Collections.IEnumerable;
System.Collections.IEnumerable second = obj2 as System.Collections.IEnumerable;
var en = first.GetEnumerator();
var en2 = second.GetEnumerator();
int i = 0;
while (en.MoveNext())
{
if (!en2.MoveNext())
return path + ": enumerable size differs";
string res = Compare(en.Current, en2.Current, path);
if (res != null)
return res + " (Index " + i + ")";
i++;
}
}
else
{
foreach (PropertyInfo pi in type.GetProperties(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public))
{
try
{
var val = pi.GetValue(obj1);
var tval = pi.GetValue(obj2);
if (path.EndsWith("." + pi.Name))
return null;
var pathNew = (path.Length == 0 ? "" : path + ".") + pi.Name;
string res = Compare(val, tval, pathNew);
if (res != null)
return res;
}
catch (TargetParameterCountException)
{
//index property
}
}
foreach (FieldInfo fi in type.GetFields(BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public))
{
var val = fi.GetValue(obj1);
var tval = fi.GetValue(obj2);
if (path.EndsWith("." + fi.Name))
return null;
var pathNew = (path.Length == 0 ? "" : path + ".") + fi.Name;
string res = Compare(val, tval, pathNew);
if (res != null)
return res;
}
}
return null;
}
আপনি এখন json.net ব্যবহার করতে পারেন। শুধু নুগেটে যান এবং এটি ইনস্টল করুন।
এবং আপনি এর মতো কিছু করতে পারেন:
public bool Equals(SamplesItem sampleToCompare)
{
string myself = JsonConvert.SerializeObject(this);
string other = JsonConvert.SerializeObject(sampleToCompare);
return myself == other;
}
আপনি ফ্যানসিয়ার পেতে চাইলে আপনি সম্ভবত অবজেক্টের জন্য একটি এক্সটেনশন পদ্ধতি তৈরি করতে পারেন। দয়া করে মনে রাখবেন এটি কেবল সর্বজনীন বৈশিষ্ট্যের সাথে তুলনা করে। আপনি যদি তুলনাটি করেন তবে আপনি যদি কোনও সরকারী সম্পত্তি উপেক্ষা করতে চান তবে আপনি [জসনআইগনোর] বৈশিষ্ট্যটি ব্যবহার করতে পারেন।