This is a refactoring question.
How to merge all these Check() methods into one single Generic Check() method since their method bodies are the same?
ppublic class ChangeDetector : IChangeDetector
{
private readonly IEqualityHelper _equalityHelper;
public ChangeDetector(IEqualityHelper equalityHelper)
{
_equalityHelper = equalityHelper;
}
public bool ChangeDetected { get; private set; }
public void Check<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new ()
{
if (!this._equalityHelper.Equals(existingList, newList))
{
NotifyChange();
}
}
public void CheckEntities<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new()
{
if (!this._equalityHelper.Equals(existingObj, newObj))
{
NotifyChange();
}
}
public void Check(string existing, string newVal)
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
public void Check<T>(T existing, T newVal) where T : struct
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
public void Check<T>(T? existing, T? newVal) where T : struct
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
private void NotifyChange()
{
ChangeDetected = true;
}
}
My EqualityHelper class members have different body though which is fine:
public class EqualityHelper : IEqualityHelper
{
public bool Equals<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new()
{
if (existingList == null || existingList.Count == 0)
{
if (newList != null && newList.Count > 0)
{
return false;
}
}
else
{
if (newList == null
|| existingList.Count != newList.Count
|| newList.Any(newListItem => existingList.Any(existingListItem => existingListItem.Id == newListItem.Id)))
{
return false;
}
}
return true;
}
public bool Equals<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new()
{
if (existingObj == null)
{
if (newObj != null)
{
return false;
}
}
else
{
if (newObj == null || existingObj.Id != newObj.Id)
{
return false;
}
}
return true;
}
public bool Equals(string existing, string newVal)
{
return string.Equals(existing, newVal);
}
public bool Equals<T>(T existing, T newVal) where T : struct
{
return !existing.Equals(newVal);
}
public bool Equals<T>(T? existing, T? newVal) where T : struct
{
if ((existing.HasValue && !newVal.HasValue)
|| (!existing.HasValue && newVal.HasValue)
|| existing.Equals(newVal))
{
return false;
}
return true;
}
}
The method bodies aren't really the same, since they're all calling different Equals() methods. What you're intending to do would (if I understand the question correctly) finish up with one Handle<T>() method where T could be any type. Thinking about what you're trying to express in the code, it seems fair that if you have one Handle<T>() method, that ought to be able to call one Equals<T>() method. That way, you can implement your handling logic once (and potentially this becomes more complex later but you only need to write it once) and you delegate the tricky business of comparing objects to your equality comparer class.
Just because the method bodies are looking similar doesn't mean the method signatures can be merged. Each of your five Handle methods calls five different Equals-methods, so unless you can merge the five Equals methods, you can't merge the Handle methods. You can't do that of course because the Equals method implementations are different. Remember that which of the Equals-method are to be called is decided compile-time, not runtime.
Edit: What you could do is change the signature of both Handle/Check and Equals to Check(object existing, object equals) and Equals(object existing, object equals). Then in the Equals-method perform a runtime type-check which results in a switch-case to the five Equals-method you already have with the help of type casting. This would make the implementation slower and only arguably more maintainable. I'm not sure I would go down that route.
Related
So I am creating a BST and want it to be a generic tree, right now I am developing the Node<T> class. I need some help with some of the operator overloading specifics. Class is below:
public class Node<T> where T : IComparable
{
//Private member data
private T data;
private Node<T> left;
private Node<T> right;
//private readonly IComparer<T> _comparer;
//Node constructor
public Node()
{
data = default(T); //
left = null;
right = null;
}
//Setters/getters for node private data members
public T Data
{
get { return data; }
set { data = value; }
}
public Node<T> Left
{
get { return left; }
set { left = value; }
}
public Node<T> Right
{
get { return right; }
set { right = value; }
}
public static bool operator ==(Node<T> lhs, Node<T> rhs)
{
if((lhs.Data).CompareTo(rhs.Data) == 0)
{
return true;
}
else
{
return false;
}
}
public static bool operator !=(Node<T> lhs, Node<T> rhs)
{
if (lhs.Data.CompareTo(rhs.Data) != 0)
{
return true;
}
else
{
return false;
}
}
}
But Visual Studio (and sources I have seen online) say I need to overload the Object.Equals(object o) method and also the Object.GetHashCode.
From what I know about .Equals just through using C#, it's like value type semantics, or will compare the values of 2 objects, instead of their references, aka checking if they are actually the same object, which I think is what == usually does when comparing objects. So this is what I tried to do:
public override bool Equals(Object obj)
{
if ((lhs.Data).CompareTo(rhs.Data) == 0)
{
return true;
}
else
{
return false;
}
}
It's basically the same as my == operator, but it doesn't work because the lhs/rhs parameters don't exist. I have no idea how do accomplish this for my case since how I believe it will be called is n1.Equals(n2) and will check to see if the data values are the same for the nodes. Examples online are unclear to me. I also have no idea why I have to involve this hash method at all, but I am still trying to do research on that. Mostly curious about the Equals override for now.
Make sure you implement the Equals method according to the MS guide. Here is my snippet. I use all the time:
// override object.Equals
public override bool Equals(object obj)
{
// shortcut
if (object.ReferenceEquals(this, obj))
{
return true;
}
// check for null and make sure we do not break oop / inheritance
if (obj == null || GetType() != obj.GetType())
{
return false;
}
// TODO: write your implementation of Equals() here
// do not call base.equals !
throw new NotImplementedException();
return false;
}
public static bool operator ==(Class lobj, Class robj)
{
// users expect == working the same way as Equals
return object.Equals(lobj, robj);
}
public static bool operator !=(Class lobj, Class robj)
{
return !object.Equals(lobj, robj);
}
// override object.GetHashCode
public override int GetHashCode()
{
// TODO: write your implementation of GetHashCode() here
// return field.GetHashCode() ^ field2.GetHashCode() ^ base.GetHashCode();
// or simply return the unique id if any
throw new NotImplementedException();
}
I'm trying to apply Specification pattern to my validation logic. But I have some problems with async validation.
Let's say I have an entity AddRequest (has 2 string property FileName and Content) that need to be validated.
I need to create 3 validators:
Validate if FileName doesn't contains invalid characters
Validate if Content is correct
Async validate if file with FileName is exists on the database. In this case I should have something like Task<bool> IsSatisfiedByAsync
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
My version of ISpecification (I need only And)
public interface ISpecification
{
bool IsSatisfiedBy(object candidate);
ISpecification And(ISpecification other);
}
AndSpecification
public class AndSpecification : CompositeSpecification
{
private ISpecification leftCondition;
private ISpecification rightCondition;
public AndSpecification(ISpecification left, ISpecification right)
{
leftCondition = left;
rightCondition = right;
}
public override bool IsSatisfiedBy(object o)
{
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
}
}
To validate if file exists I should use:
await _fileStorage.FileExistsAsync(addRequest.FileName);
How can I write IsSatisfiedBy for that check if I really need do that async?
For example here my validator (1) for FileName
public class FileNameSpecification : CompositeSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
{
return false;
}
if (request.FileName.Length > 1024)
{
return false;
}
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
{
return false;
}
return true
}
}
I need to create FileExistsSpecification and use like:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if(validations.IsSatisfiedBy(addRequest))
{ ... }
But how can I create FileExistsSpecification if I need async?
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
You can define both synchronous and asynchronous interfaces, but any general-purpose composite implementations would have to only implement the asynchronous version.
Since asynchronous methods on interfaces mean "this might be asynchronous" whereas synchronous methods mean "this must be synchronous", I'd go with an asynchronous-only interface, as such:
public interface ISpecification
{
Task<bool> IsSatisfiedByAsync(object candidate);
}
If many of your specifications are synchronous, you can help out with a base class:
public abstract class SynchronousSpecificationBase : ISpecification
{
public virtual Task<bool> IsSatisfiedByAsync(object candidate)
{
return Task.FromResult(IsSatisfiedBy(candidate));
}
protected abstract bool IsSatisfiedBy(object candidate);
}
The composites would then be:
public class AndSpecification : ISpecification
{
...
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await leftCondition.IsSatisfiedByAsync(o) && await rightCondition.IsSatisfiedByAsync(o);
}
}
public static class SpecificationExtensions
{
public static ISpecification And(ISpeicification #this, ISpecification other) =>
new AndSpecification(#this, other);
}
and individual specifications as such:
public class FileExistsSpecification : ISpecification
{
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await _fileStorage.FileExistsAsync(addRequest.FileName);
}
}
public class FileNameSpecification : SynchronousSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
return false;
if (request.FileName.Length > 1024)
return false;
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
return false;
return true;
}
}
Usage:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if (await validations.IsSatisfiedByAsync(addRequest))
{ ... }
I don't know, why you need async operations in a sync driven pattern.
Imagine, if the first result is false and you have two or more async checks, it would be a waste in performance.
If you want to know, how to get an async request back in sync, you can try to use the following:
public class FileExistsSpecification : CompositeSpecification
{
public override bool IsSatisfiedBy(object o)
{
var addRequest = (AddRequest)o
Task<bool> fileExistsResult = _fileStorage.FileExistsAsync(addRequest.FileName);
fileExistsResult.Wait();
return fileExistsResult.Result;
}
}
You should also use the generics approach.
I think your main goal here is to make sure that code finishes as soon as possible for evaluating a composite specification, when executing child specifications and one or more may take a while, yes? It's always possible for calling code outside of your pattern implementation to invoke a specification asynchronously; it's not really your concern at that point.
So, in light of that, how about giving your ISpecification an extra property?
public interface ISpecification
{
bool IsAsynchronous { get; }
bool IsSatisfiedBy(object o);
}
Then, for non-composite synchronous or asynchronous-type specifications, hard-code the return value for IsAsynchronous. But in composite ones, base it on the children, to wit:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!this.IsAsynchronous)
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
But taking this a bit further, you don't want to waste performance. Hence why not evaluate the fast, synchronous child first when there's one sync and one async? Here's a closer-to-finished version of the basic idea:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!left.IsAsynchronous)
{
if (!right.IsAsynchronous)
{
return left.IsSatisfiedBy(o) && right.IsSatisfiedBy(o);
}
else
{
if (!left.IsSatisfiedBy(o)) return false;
return right.IsSatisfiedBy(o);
}
}
else if (!right.IsAsynchronous)
{
if (!right.IsSatisfiedBy(o)) return false;
return left.IsSatisfiedBy(o);
}
else
{
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
}
I'm working with RPC(protobuf-remote) and I need to do some checking in case the other end(server) is down. Let's say I've lot's of RPC methods, like:
public FirstObj First(string one, string two)
{
if (rpc == null)
return (FirstObj)Activator.CreateInstance(typeof(FirstObj));
return rpc.First(one, two);
}
public SecondObj Second(string one)
{
if (rpc == null)
return (SecondObj)Activator.CreateInstance(typeof(SecondObj));
return rpc.Second(one);
}
public ThirdObj Third()
{
if (rpc == null)
return (ThirdObj)Activator.CreateInstance(typeof(ThirdObj));
return rpc.Third();
}
Is there anyway to change this repetitive null-checking code? So I could write something like:
public FirstObj First(string one, string two)
{
return rpc.First(one, two);
}
Which would do null-checking and would create object by it's type if RPC server is down, so I will get default values of required object.
You could create such extension method:
public static class RpcExtension
{
public static T GetObject<T>(this RPC rpc, Func<RPC, T> func)
where T: class , new ()
{
if (rpc == null)
{
return Activator.CreateInstance<T>();
}
return func(rpc);
}
}
for this usage:
var first = rpc.GetObject(r => r.First(a, b));
You can simplify your code with a generic method:
private static T Make<T>() {
return (T)Activator.CreateInstance(typeof(T));
}
public FirstObj First(string one, string two) {
return rpc == null ? Make<FirstObj>() : rpc.First(one, two);
}
public SecondObj Second(string one) {
return rpc == null ? Make<SecondObj>() : rpc.Second(one);
}
public ThirdObj Third() {
return rpc == null ? Make<ThirdObj>() : rpc.Third();
}
If FirstObj, SecondObj, and ThirdObj types are all classes, not structs or primitives, and rpc never returns null for them, you can do this:
public static T RpcOrDefault<T>(T obj) where T : class {
return obj ?? (T)Activator.CreateInstance(typeof(T));
}
and call it
FirstObj first = RpcOrDefault(rpc?.First(one, two));
// ^
Note the ? in ?. which shields you from null reference exceptions.
I have two classes which both derive from the same parent:
public class People{
public string BetterFoot;
public override bool Equals(object obj){
if (obj == null || this.GetType() != obj.GetType())
return false;
People o = (People)obj;
return (this.BetterFoot == o.BetterFoot);
}
public class LeftiesOrRighties: People{
public string BetterHand;
public override bool Equals(object obj){
if (obj == null || this.GetType() != obj.GetType())
return false;
LeftiesOrRighties o = (LeftiesOrRighties)obj;
return (this.BetterFoot == o.BetterFoot) &&
(this.BetterHand == o.BetterHand)
}
}
public class Ambidextrous: People{
public string FavoriteHand;
}
(There are GetHashCodes in there, too, but I know that they work.)
I'd like to compare collections of them, based on their root Equals():
ThoseOneHanded = new List<LeftiesOrRighties>(){new LeftiesOrRighties(){BetterFoot = "L"}};
ThoseTwoHanded = new List<Ambidextrous>(){new Ambidextrous(){BetterFoot = "L"}};
//using NUnit
Assert.That ((People)ThoseOneHanded[0], Is.EqualTo((People)ThoseTwoHanded[0])));
Unfortunately, this returns false.
Why? Shouldn't the casting make them (for all intents and purposes, if not exactly) the same type, and thus use the base methods? And if not, how do I truly cast the underlying type back to People?
Cast doesn't change the object itself, so the result of GetType will always be the same and so your this.GetType() != obj.GetType() will be true and so the function will return false.
The following logic could potentially gain the behaviour you want (and you don't need to cast to People)
public class People
{
public string BetterFoot;
public override bool Equals(object obj)
{
var o = obj as People;
if (o == null) return false;
return (this.BetterFoot = o.BetterFoot);
}
public class LeftiesOrRighties: People
{
public string BetterHand;
public override bool Equals(object obj)
{
var o = obj as LeftiesOrRighties;
if ( o == null) return base.Equals(obj);
return (this.BetterFoot = o.BetterFoot) && (this.BetterHand = o.BetterHand)
}
}
public class Ambidextrous: People
{
public string FavoriteHand;
}
As Bob Vale pointed out, the cast does not change type.
The standard solution used across the .NET Framework is to use custom object implementing IEqualityComparer or its generic variant. Then your compare/find method takes 2 objects/collections and uses comparer to perform the custom comparison.
I.e. many LINQ methods take custom compare to find/filter objects like
Enumerable.Distinct
public static IEnumerable<TSource> Distinct<TSource>(
this IEnumerable<TSource> source,
IEqualityComparer<TSource> comparer
)
Sample comparer:
class Last3BitsComparer : IEqualityComparer<int>
{
public bool Equals(int b1, int b2)
{
return (b1 & 3) == (b2 & 3);
}
public int GetHashCode(int bx)
{
return bx & 3;
}
}
I have defined the following interface:
public interface IHaveAProblem
{
string Issue { get; set; }
}
And here is the implementation of IHaveAProblem:
public class SomeProblem : IHaveAProblem
{
public string Issue { get; set; }
public override bool Equals(object obj)
{
SomeProblem otherObj = obj as SomeProblem;
if (otherObj == null)
{
return false;
}
return this.Issue == otherObj.Issue;
}
public override int GetHashCode()
{
return base.GetHashCode();
}
public static bool operator ==(SomeProblem rhs, SomeProblem lhs)
{
// Null check
if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null))
{
// Both are null. They do equal each other
return true;
}
// Only 1 is null the other is not so they do not equal
return false;
}
return rhs.Equals(lhs);
}
public static bool operator !=(SomeProblem rhs, SomeProblem lhs)
{
// Null check
if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null))
{
if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null))
{
// Both are null. They do equal each other
return false;
}
// Only 1 is null the other is not so they do not equal
return true;
}
return !rhs.Equals(lhs);
}
}
When I use the object, I can get the correct results for the == compare:
SomeProblem firstTest = new SomeProblem()
{
Issue = "Hello World"
};
SomeProblem secondTest = new SomeProblem()
{
Issue = "Hello World"
};
// This is true
bool result = firstTest == secondTest;
However, when I try to compare the interfaces, it is doing a memory compare rather than the operator == on SomeProblem:
IHaveAProblem firstProblem = new SomeProblem()
{
Issue = "Hello World"
};
IHaveAProblem secondProblem = new SomeProblem()
{
Issue = "Hello World"
};
Is it possible to have the interface use the == on SomeProblem rather than a memory compare?
I know I can do a firstProblem.Equals(secondProblem) and get the proper results. However, I am creating a framework and I will not know how it is used in the end. I thought == would work correctly.
The operator == is static. You cannot define static methods for interfaces in C#. Also, for all operators at least one of the argument types needs to be of the same type as the class it is defined in, therefore: No operator overloading for interfaces :(
What you CAN do is use an abstract class instead - and define the operator there. Again, the operator may NOT be virtual (since static methods cannot be virtual...)
[Edited, reason see comment.]
I konw, this is an old question, but all examples provided show how to compare two class instances, and no one points out how to compare two interface instances.
In some cases, this is the DRYest way to compare interfaces.
public interface IHaveAProblem
{
string Issue { get; set; }
}
public class IHaveAProblemComparer : IComparer<IHaveAProblem>, IEqualityComparer<IHaveAProblem>
{
public int Compare(IHaveAProblem x, IHaveAProblem y)
{
return string.Compare(x.Issue, y.Issue);
}
public bool Equals(IHaveAProblem x, IHaveAProblem y)
{
return string.Equals(x.Issue, y.Issue);
}
public int GetHashCode(IHaveAProblem obj)
{
return obj.GetHashCode();
}
}
Usage?
IHaveAProblemComparer comparer = new IHaveAProblemComparer();
List<IHaveAProblem> myListOfInterfaces = GetSomeIHaveAProblemObjects();
myListOfInterfaces.Sort(comparer); // items ordered by Issue
IHaveAProblem obj1 = new SomeProblemTypeA() { Issue = "Example1" };
IHaveAProblem obj2 = new SomeProblemTypeB() { Issue = "Example2" };
bool areEquals = comparer.Equals(obj1, obj2); // False
IIRC (and I could be wrong here), C# interfaces don't allow operator overloading.
But in this case that's okay. The == operator normally maps to reference equality. It sounds like you want value equality, and that means you want to force them to override the .Equals() (and consequently also .GetHashCode()) functions. You do that by having your interface inherit from IEquatable.
Have you tried implementing IComparable?
Like this:
public interface IHaveAProblem : IComparable
{
string Issue { get; set; }
}
And then in the implementation of the class:
public class SomeProblem : IHaveAProblem
{
public string Issue { get; set; }
...
public int CompareTo(object obj)
{
return Issue.CompareTo(((SomeProblem)obj).Issue);
}
}
Note that, this works only when you compare two instances of SomeProblem, but not any other implementations of the IHaveAProblem interface.
Not sure if there could occur a NullReferenceException.