Reflection based comparion of two object values [duplicate] - c#

This question already has an answer here:
Comparing two objects by iterating recursively through all the properties' properties?
(1 answer)
Closed 7 years ago.
Are there any libraries/frameworks for .net that would take two objects of the same type and using reflection match values of all the properties?
I had to compare two objects having 2 Nullable DateTime properties and the code lookes ugly as hell:
private bool SameValues(ExpiryDates ExpiryDates1, ExpiryDates ExpiryDates2)
{
//Assume they are the same value and then look for differences
bool result = true;
if (ExpiryDates1.PSL_ExpiryDate.HasValue != ExpiryDates2.PSL_ExpiryDate.HasValue)
{
result = false;
}
if (ExpiryDates1.MNL_ExpiryDate.HasValue != ExpiryDates2.MNL_ExpiryDate.HasValue)
{
result = false;
}
if ((ExpiryDates1.MNL_ExpiryDate != null) && (ExpiryDates2.MNL_ExpiryDate != null))
if (ExpiryDates1.MNL_ExpiryDate.Value != ExpiryDates2.MNL_ExpiryDate.Value)
result = false;
if ((ExpiryDates1.PSL_ExpiryDate != null) && (ExpiryDates2.PSL_ExpiryDate != null))
if (ExpiryDates1.PSL_ExpiryDate.Value != ExpiryDates2.PSL_ExpiryDate.Value)
result = false;
return result;
}

There is no library avaiable as per my knowldege but in .NEt framework for comparison of same type of object we have IComparare interface that you can use and do comparison between two object of same type.
public class BoxComp : IComparer<Box>
{
// Compares by Height, Length, and Width.
public int Compare(Box x, Box y)
{
///you code to do comparison
}
}
you can aslo make it generic.
You can check this : Compare .NET Objects but i suggest to go for comparare impmentation as there is no big need as you just want to compare datetime of two object.

Related

How to compare two List<string[]> in C# [duplicate]

This question already has answers here:
Quickest way to compare two generic lists for differences
(18 answers)
Closed 3 years ago.
Automation - selenium using C#
We are reading a table which returns value in List<string[]>. We need to compare the values before and after an action performed, which should not affect the table content.
Is there a way to compare both
List<string[]> ExpRequestItemsWithSection
with
List<string[]> ActRequestItemsWithSection
Till now i was using below code and it works fine. But is there any other way to compare both the collections? Any idea of making this quicker and less resource intensive as i need to process a lot of lists?
bool isRequestsMatch = true;
for (int i = 0; i < ActRequestItemsWithSection.Count; i++)
{
if (!((ActRequestItemsWithSection[i][0] == ExpRequestItemsWithSection[i][0]) &&
(ActRequestItemsWithSection[i][1] == ExpRequestItemsWithSection[i][1])))
isRequestsMatch = false;
}
PFB screenshot from Immediate window
Well, if order matters, i.e.
{["A", "B"]} != {["B, A"]} // A and B swapped within the array
and
{ {
["A", "B"], ["C"], // [A, B] and [C] arrays are swapped
["C"] != ["A, "B"]
} }
Then you can check equality with a help of Linq:
bool equals = (ExpRequestItemsWithSection.Count == ActRequestItemsWithSection.Count) &&
ExpRequestItemsWithSection
.Zip(ActRequestItemsWithSection, (left, right) => left.SequenceEqual(right))
.All(item => item);
There is a System.Collections.StructuralComparisons.StructuralEqualityComparer, but for some obscure reason it is written in an ugly nongeneric way that makes it hard to use as a generic IEqualityComparer<>.
If you wrap it like this:
class GenericStructuralEqualityComparer<T> : EqualityComparer<T>
where T : System.Collections.IStructuralEquatable
{
public override bool Equals(T x, T y)
=> System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals(x, y);
public override int GetHashCode(T obj)
=> System.Collections.StructuralComparisons.StructuralEqualityComparer.GetHashCode(obj);
}
then you can do SequenceEqauls on the outer (List<>) level:
if (!
ExpRequestItemsWithSection.SequenceEqual(ActRequestItemsWithSection,
new GenericStructuralEqualityComparer<string[]>())
)
Maybe prettier than the .Zip solution?
Addition: If you like .Zip, you can use StructuralEqualityComparer without a wrapping class:
if (
ExpRequestItemsWithSection.Count != ActRequestItemsWithSection.Count
||
ExpRequestItemsWithSection.Zip(ActRequestItemsWithSection,
System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals)
.Contains(false)
)
This uses the method group System.Collections.StructuralComparisons.StructuralEqualityComparer.Equals whose signature and return type is good enough for a Func<string[], string[], bool> which .Zip takes (tried with C# 7.3 compiler).
Maybe you are looking for this answer
if (a1.SequenceEqual(a2))

A safe way to get some deep value [duplicate]

This question already has answers here:
Elegant way to avoid NullReferenceException in C#
(4 answers)
Closed 3 years ago.
Suppose I have a fairly deep class, and I need to get some field embedded deep within
int? result = this.child.button.data;
return result;
And at any point, it could be pointing to a null, in which case I want to return null as well. A common approach would be
if (this.child != null && this.child.button!= null) {
return this.child.button.data;
} else {
return null;
}
But if the field is REALLY deep nested, then the only solution I can think of is this:
int? result = null;
try {
result = this.child.button.handler.controller.renderer.data;
} catch (NullReferenceException ex) {
// Do nothing here
}
Is this the correct approach, or is there a better solution?
you may check the null conditional operator in C# - ?.
Like:
result = this?.child?.button?.handler?.controller?.renderer?.data;

C# Dictionary throws KeyNotFoundException when key exists

I am storing a 2D array that represents a distance matrix between vectors as a Dictionary<DistanceCell, double>. My implementation of DistanceCell has two string fields representing the vectors being compared.
class DistanceCell
{
public string Group1 { get; private set; }
public string Group2 { get; private set; }
public DistanceCell(string group1, string group2)
{
if (group1 == null)
{
throw new ArgumentNullException("group1");
}
if (group2 == null)
{
throw new ArgumentNullException("group2");
}
this.Group1 = group1;
this.Group2 = group2;
}
}
Since I'm using this class as a key, I overrode Equals() and GetHashCode():
public override bool Equals(object obj)
{
// False if the object is null
if (obj == null)
{
return false;
}
// Try casting to a DistanceCell. If it fails, return false;
DistanceCell cell = obj as DistanceCell;
if (cell == null)
{
return false;
}
return (this.Group1 == cell.Group1 && this.Group2 == cell.Group2)
|| (this.Group1 == cell.Group2 && this.Group2 == cell.Group1);
}
public bool Equals(DistanceCell cell)
{
if (cell == null)
{
return false;
}
return (this.Group1 == cell.Group1 && this.Group2 == cell.Group2)
|| (this.Group1 == cell.Group2 && this.Group2 == cell.Group1);
}
public static bool operator ==(DistanceCell a, DistanceCell b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If either is null, return false.
// Cast a and b to objects to check for null to avoid calling this operator method
// and causing an infinite loop.
if ((object)a == null || (object)b == null)
{
return false;
}
return (a.Group1 == b.Group1 && a.Group2 == b.Group2)
|| (a.Group1 == b.Group2 && a.Group2 == b.Group1);
}
public static bool operator !=(DistanceCell a, DistanceCell b)
{
return !(a == b);
}
public override int GetHashCode()
{
int hash;
unchecked
{
hash = Group1.GetHashCode() * Group2.GetHashCode();
}
return hash;
}
As you can see, one of the requirements of DistanceCell is that Group1 and Group2 are interchangeable. So for two strings x and y, DistanceCell("x", "y") must equal DistanceCell("y", "x"). This is why I implemented GetHashCode() with multiplication because DistanceCell("x", "y").GetHashCode() must equal DistanceCell("y", "x").GetHashCode().
The problem that I'm having is that it works correctly roughly 90% of the time, but it throws a KeyNotFoundException or a NullReferenceException the remainder of the time. The former is thrown when getting a key from the dictionary, and the latter when I iterate over the dictionary with a foreach loop and it retrieves a key that is null that it then tries to call Equals() on. I suspect this has something to do with an error in my GetHashCode() implementation, but I'm not positive. Also note that there should never be a case where the key wouldn't exist in the dictionary when I check it because of the nature of my algorithm. The algorithm takes the same path every execution.
Update
I just wanted to update everyone that the problem is fixed. It turns out that it had nothing to do with my Equals() or GetHashCode() implementation. I did some extensive debugging and found that the reason I was getting a KeyNotFoundException was because the key didn't exist in the dictionary in the first place, which was strange because I was positive that it was being added. The problem was that I was adding the keys to the dictionary with multiple threads, and according to this, the c# Dictionary class isn't thread-safe. So the timing must have been perfect that an Add() failed and thus the key was never added to the dictionary. I believe this can also explain how the foreach loop was bringing up a null key on occasion. The Add()'s from multiple threads must have messed up some internal structures in the dictionary and introduced a null key.
Thanks to every one for your help! I'm sorry that it ended up being a fault entirely on my end.
Take a look at this blog post by Eric Lippert
It says that the result of GetHashCode should never change even if you change the content of the object. The reason is that Dictionary is using buckets for faster indexing. Once you change the GetHasCode result, the Dictionary will not be able to find the right bucket for your object and this can lead to "Key not found"
I might be wrong, but it is worth testing.
I believe what is missing for you is this answer
Using an object as a generic Dictionary key
You probably not stating you implement IEquatable interface
To me your code looks correct. (It can possibly be (micro-)optimized, but it looks as if it will be correct in all cases.) Can you provide some code where you create and use the Dictionary<DistanceCell, double>, and things go bad? The problem may lie in code you haven't shown us.

Need to Compare Two Generic Objects Using Greater Than or Less Than [duplicate]

This question already has answers here:
How to compare values of generic types?
(8 answers)
Closed 9 years ago.
Synopsis: I have a need to take two generic C# objects, and if they are numerical, compare them using either less than or greater than comparisons.
Problem: I can't figure out how to have my class implement IComparable as described in this post: Having to implement a generic less than and greater than operation. If that's not even the proper path to take, then I need to know that as well.
Background: I have implemented the RequiredIf ValidationAttribute found at A more complex custom validator but needed the > and < options in addition to an equals comparison.
Code (taken from A more complex custom validator, one-third down the page):
private bool IsRequired(object actualPropertyValue)
{
switch (Comparison)
{
case Comparison.IsLessThan:
case Comparison.IsLessThanOrEqualTo:
case Comparison.IsGreaterThan:
case Comparison.IsGreaterThanOrEqualTo:
if (!Value.IsNumber())
{
throw new Exception("The selected comparison option is only applicable to numeric values");
}
break;
}
switch (Comparison)
{
case Comparison.IsNotEqualTo:
return actualPropertyValue == null || !actualPropertyValue.Equals(Value);
case Comparison.IsEqualTo:
return actualPropertyValue != null && actualPropertyValue.Equals(Value);
case Comparison.IsGreaterThan:
// THIS LINE FAILS BECAUSE actualPropertyValue DOESN'T IMPLEMENT IComparable
return actualPropertyValue != null && (actualPropertyValue.CompareTo(Value) > 0);
// The rest of the comparison cases go here...
default:
throw new Exception("Comparison value is not defined");
}
}
Static Helper Extensions:
public static bool IsNumber(this object value)
{
if (value is sbyte) return true;
if (value is byte) return true;
if (value is short) return true;
if (value is ushort) return true;
if (value is int) return true;
if (value is uint) return true;
if (value is long) return true;
if (value is ulong) return true;
if (value is float) return true;
if (value is double) return true;
if (value is decimal) return true;
return false;
}
It sounds like you should just be able to cast actualPropertyValue to IComparable:
IComparable comparable = (IComparable) actualPropertyValue;
return comparable != null && comparable.CompareTo(Value) > 0;
Note that your use of the word "generic" is curious here. If you actually made it generic, you could write:
private bool IsRequired<T>(T actualPropertyValue) where T : IComparable
Then you wouldn't need the cast.
int MyCompare (object a, object b)
{
var ac = a as IComparable;
var bc = b as IComparable;
if (ac == null || bc == null)
throw new NotSupportedException();
return ac.CompareTo(bc);
}

How to implement VARIANT in Protobuf

As part of my protobuf protocol I require the ability to send data of a dynamic type, a little bit like VARIANT. Roughly I require the data to be an integer, string, boolean or "other" where "other" (e.g. DateTime) is serialized as a string. I need to be able to use these as a single field and in lists in a number of different locations in the protocol.
How can this best be implemented while keeping message size minimal and performance optimal?
I'm using protobuf-net with C#.
EDIT:
I've posted a proposed answer below which uses what I think is the minimum of memory required.
EDIT2:
Created a github.com project at http://github.com/pvginkel/ProtoVariant with a complete implementation.
Jon's multiple optionals covers the simplest setup, especially if you need cross-platform support. On the .NET side (to ensure you don't serialize unnecessary values), simply return null from any property that isn't a match, for example:
public object Value { get;set;}
[ProtoMember(1)]
public int? ValueInt32 {
get { return (Value is int) ? (int)Value : (int?)null; }
set { Value = value; }
}
[ProtoMember(2)]
public string ValueString {
get { return (Value is string) ? (string)Value : null; }
set { Value = value; }
}
// etc
You can also do the same using the bool ShouldSerialize*() pattern if you don't like the nulls.
Wrap that up in a class and you should be fine to use that at either the field level or list level. You mention optimal performance; the only additional thing I can suggest there is to perhaps consider treating as a "group" rather than "submessage", as this is easier to encode (and just as easy to decode, as long as you expect the data). To do that, use the Grouped data-format, via [ProtoMember], i.e.
[ProtoMember(12, DataFormat = DataFormat.Group)]
public MyVariant Foo {get;set;}
However, the difference here can be minimal - but it avoids some back-tracking in the output stream to fix the lengths. Either way, in terms of overheads a "submessage" will take at least 2 bytes; "at least one" for the field-header (perhaps taking more if the 12 is actually 1234567) - and "at least one" for the length, which gets bigger for longer messages. A group takes 2 x the field-header, so if you use low field-numbers this will be 2 bytes regardless of the length of the encapsulated data (it could be 5MB of binary).
A separate trick, useful for more complex scenarios but not as interoperable, is generic inheritance, i.e. an abstract base class that has ConcreteType<int>, ConcreteType<string> etc listed as subtypes - this, however, takes an extra 2 bytes (typically), so is not as frugal.
Taking another step further away from the core spec, if you genuinely can't tell what types you need to support, and don't need interoperability - there is some support for including (optimized) type information in the data; see the DynamicType option on ProtoMember - this takes more space than the other two options.
You could have a message like this:
message Variant {
optional string string_value = 1;
optional int32 int32_value = 2;
optional int64 int64_value = 3;
optional string other_value = 4;
// etc
}
Then write a helper class - and possibly extension methods - to ensure that you only ever set one field in the variant.
You could optionally include a separate enum value to specify which field is set (to make it more like a tagged union) but the ability to check the optional fields just means the data is already there. It depends on whether you want the speed of finding the right field (in which case add the discriminator) or the space efficiency of only including the data itself (in which case don't add the discriminator).
That's a general Protocol Buffer approach. There may be something more protobuf-net specific, of course.
Asking questions always helps me think. I found a way to get the number of bytes used for transfer to a bare minimum.
What I've done here is make use of optional properties. Say I want to send an int32. When the value isn't zero, I can just check a property on the message for whether it has a value. Otherwise, I set a type to INT32_ZERO. This way I can correctly store and reconstruct the value. The example below has this implementation for a number of types.
The .proto file:
message Variant {
optional VariantType type = 1 [default = AUTO];
optional int32 value_int32 = 2;
optional int64 value_int64 = 3;
optional float value_float = 4;
optional double value_double = 5;
optional string value_string = 6;
optional bytes value_bytes = 7;
optional string value_decimal = 8;
optional string value_datetime = 9;
}
enum VariantType {
AUTO = 0;
BOOL_FALSE = 1;
BOOL_TRUE = 2;
INT32_ZERO = 3;
INT64_ZERO = 4;
FLOAT_ZERO = 5;
DOUBLE_ZERO = 6;
NULL = 7;
}
And accompanying partial .cs file:
using System;
using System.Collections.Generic;
using System.Text;
using System.Globalization;
namespace ConsoleApplication6
{
partial class Variant
{
public static Variant Create(object value)
{
var result = new Variant();
if (value == null)
result.Type = VariantType.NULL;
else if (value is string)
result.ValueString = (string)value;
else if (value is byte[])
result.ValueBytes = (byte[])value;
else if (value is bool)
result.Type = (bool)value ? VariantType.BOOLTRUE : VariantType.BOOLFALSE;
else if (value is float)
{
if ((float)value == 0f)
result.Type = VariantType.FLOATZERO;
else
result.ValueFloat = (float)value;
}
else if (value is double)
{
if ((double)value == 0d)
result.Type = VariantType.DOUBLEZERO;
else
result.ValueDouble = (double)value;
}
else if (value is decimal)
result.ValueDecimal = ((decimal)value).ToString("r", CultureInfo.InvariantCulture);
else if (value is DateTime)
result.ValueDatetime = ((DateTime)value).ToString("o", CultureInfo.InvariantCulture);
else
throw new ArgumentException(String.Format("Cannot store data type {0} in Variant", value.GetType().FullName), "value");
return result;
}
public object Value
{
get
{
switch (Type)
{
case VariantType.BOOLFALSE:
return false;
case VariantType.BOOLTRUE:
return true;
case VariantType.NULL:
return null;
case VariantType.DOUBLEZERO:
return 0d;
case VariantType.FLOATZERO:
return 0f;
case VariantType.INT32ZERO:
return 0;
case VariantType.INT64ZERO:
return (long)0;
default:
if (ValueInt32 != 0)
return ValueInt32;
if (ValueInt64 != 0)
return ValueInt64;
if (ValueFloat != 0f)
return ValueFloat;
if (ValueDouble != 0d)
return ValueDouble;
if (ValueString != null)
return ValueString;
if (ValueBytes != null)
return ValueBytes;
if (ValueDecimal != null)
return Decimal.Parse(ValueDecimal, CultureInfo.InvariantCulture);
if (ValueDatetime != null)
return DateTime.Parse(ValueDatetime, CultureInfo.InvariantCulture);
return null;
}
}
}
}
}
EDIT:
Further comments from #Marc Gravell have improved the implementation significantly. See the Git repository for a complete implementation of this concept.
Actually protobuf doesn't support any kind of VARIANT types.
You can try to play around using Unions, see more details here
The main idea is to define message wrapper with all existing message types as optional field, and by using union just specify which type of this concrete message it is.
See example by following the link above.
I use ProtoInclude with an abstract base type and subclasses to get the type and single value statically set. Here's the start of what that could look like for Variant:
[ProtoContract]
[ProtoInclude(1, typeof(Integer))]
[ProtoInclude(2, typeof(String))]
public abstract class Variant
{
[ProtoContract]
public sealed class Integer
{
[ProtoMember(1)]
public int Value;
}
[ProtoContract]
public sealed class String
{
[ProtoMember(1)]
public string Value;
}
}
Usage:
var foo = new Variant.String { Value = "Bar" };
var baz = new Variant.Integer { Value = 10 };
This answer gives takes a bit more space as it encodes the length of the ProtoInclude'd class instance (e.g. 1 byte for int and under < 125 byte strings). I am willing to live with this for the benefit of controlling the type statically.

Categories

Resources