C# Repetitive code with null check - c#

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.

Related

How to merge methods with the same body but different signatures together?

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.

Overriding == and != on a class

is there any way to do this on a class and still retain the capability to detect whether a variable of the Type is null ? I can do this for structs, (cause struct can't really be null, with a struct, instead of comparing x with null, you use a separate method caleld IsNull or HasValue... but you can't use that technique with a class cause when the class variable is null, of course, you can't call such an instance method on it !
public class myClass: IEquatable<myClass>
{
public int IntValue { get; set; }
public static bool operator ==(myClass cA, myClass cB)
{ return cA is myClass && cB is myClass && cB.Equals(cA); }
public static bool operator !=(myClass cA, myClass cB)
{ return !(cA == cB); }
public override bool Equals(object o)
{ return o is myClass && this == (myClass)o; }
public override bool Equals(myClass o)
{ return IntValue == o.IntValue; }
}
but when I go:
myClass x;
if (x != null) // this returns false when it should be true
{
//code to execute with x here
}
For what it's worth, the only reason I want this to be a class is because it participates in a simple inheritance relationship. This is an immutable class, and in effect what I am trying to do here is code it so it can behave like an immutable and nullable class, exactly like an immutable, nullable struct behaves (such as Nullable<int> or Nullable<float> etc.
That's why IsNull should be a static method taking a parameter. string.IsNullOrEmpty is a good example. After that, nothing prevents you from making it an extension method.
public class MyClass
{
public static bool IsNull(MyClass other)
{ return ReferenceEquals(other, null); }
public static bool HasValue(MyClass other)
{ return !IsNull(other); }
// other code
}
public static class MyClassExtension
{
public static bool IsNull(this MyClass myClass)
{
return MyClass.IsNull(myClass);
}
}
This will let you do the following without throwing:
MyClass myClass = null;
if(myClass.IsNull())
{
//...
}
If you're not initializing x so it is null, you need to do this
myClass x = new myClass();
if (x != null) {/* is true */}
You can always use:
ReferenceEquals(x, null)
this returns a boolean value showing whether x is null.
You should not do this at all.
You should only do this for an immutable class, if you really must. And then,
You should follow the guidelines
public class myClass: IEquatable<myClass>
{
public static bool operator ==(myClass cA, myClass cB)
{ return (cB == null && cA = null) || (cA is myClass && cB is myClass && cB.Equals(cA)); }
}
Why not just override GetHashCode and Equals?
when you override them both it allows you do do both == and != very easily..

Why overloading does not occur?

I have the following class:
class CrmToRealTypeConverter : IConverter
{
#region IConverter Members
public object Convert<T>(T obj)
{
return Convert(obj);
}
#endregion
private DateTime? Convert(CrmDateTime obj)
{
return obj.IsNull == false ? (DateTime?)obj.UserTime : null;
}
private int? Convert(CrmNumber obj)
{
return obj.IsNull == false ? (int?)obj.Value : null;
}
private decimal? Convert(CrmDecimal obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private double? Convert(CrmDouble obj)
{
return obj.IsNull == false ? (double?)obj.Value : null;
}
private float? Convert(CrmFloat obj)
{
return obj.IsNull == false ? (float?)obj.Value : null;
}
private decimal? Convert(CrmMoney obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
private bool? Convert(CrmBoolean obj)
{
return obj.IsNull == false ? (bool?)obj.Value : null;
}
}
I am trying to specialize the Convert method with concreate types.
Currently it just loops recursively in Convert<T>() until a stack overflow occurs.
Polymorphism doesn't work on arguments to a method call. An approach you can use it to check the type of obj, cast it to the specific type and then call the appropriate overload.
public object Convert(object obj)
{
if (obj is CrmDateTime)
return Convert((CrmDateTime)obj);
if (obj is CrmNumber)
return Convert((CrmNumber)obj);
// ...
}
Late-binding doesn't happen the way you think it does; the compiler binds the call to Convert(obj) in thepublic object Convert<T>(T obj) method to the same method (recursive call). The behaviour you appear to be expecting is that the CLR will dynamically choose the most appropriate overload to execute at run-time, but it doesn't work that way. Try something like this instead:
public object Convert<T>(T obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
var cdt = obj as CrmDateTime;
if (cdt != null)
return Convert(cdt); // bound at compile-time to DateTime? Convert(CrmDateTime)
var cn = obj as CrmNumber;
if (cn != null)
return Convert(cn); // bound at compile-time to int? Convert(CrmNumber)
// ...
throw new NotSupportedException("Cannot convert " + obj.GetType());
}
If you prefer, you can use reflection here. Such a solution would look something like:
// Making the method generic doesn't really help
public object Convert(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
// Target method is always a private, instance method
var bFlags = BindingFlags.Instance | BindingFlags.NonPublic;
// ..which takes a parameter of the obj's type.
var parameterTypes = new[] { obj.GetType() };
// Get a MethodInfo instance that represents the correct overload
var method = typeof(CrmToRealTypeConverter)
.GetMethod("Convert", bFlags, null, parameterTypes, null);
if (method == null)
throw new NotSupportedException("Cannot convert " + obj.GetType());
// Invoke the method with the forwarded argument
return method.Invoke(this, new object[] { obj });
}
The model you should follow is the model in the .Net Convert class, there is no reason for you to make the constructor a generic, it brings nothing to the table. Change the convert routines to static methods and the class itself to static:
static class CrmToRealTypeConverter : IConverter
{
#region IConverter Members
public static DateTime? Convert(CrmDateTime obj)
{
return obj.IsNull == false ? (DateTime?)obj.UserTime : null;
}
public static int? Convert(CrmNumber obj)
{
return obj.IsNull == false ? (int?)obj.Value : null;
}
public static decimal? Convert(CrmDecimal obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
public static double? Convert(CrmDouble obj)
{
return obj.IsNull == false ? (double?)obj.Value : null;
}
public static float? Convert(CrmFloat obj)
{
return obj.IsNull == false ? (float?)obj.Value : null;
}
public static decimal? Convert(CrmMoney obj)
{
return obj.IsNull == false ? (decimal?)obj.Value : null;
}
public static bool? Convert(CrmBoolean obj)
{
return obj.IsNull == false ? (bool?)obj.Value : null;
}
}
Then when you call one of the convert methods the compiler will select the proper overload to call:
CrmDateTime crmDate;
CrmToRealTypeConverter.Convert(crmDate); // Will call the static DateTime? Convert(CrmDateTime obj) overload
// or
CrmNumber crmNum;
CrmToRealTypeConverter.Convert(crmNum); // Will call the static int? Convert(CrmNumber obj) overload
// and so on...
Edit:
If you do the following:
CrmFloat num;
// ...
Object obj = num;
CrmToRealTypeConverter.Convert(obj);
it will not work as the compiler doesn't know the type to match the overload. You would have to cast it and it will work:
CrmToRealTypeConverter.Convert((CrmFloat)obj);
This occurs because the compiler doesn't know the generic type of T until runtime and binds the call to T = System.Object at compile-time, and the only function suitable to take a System.Object is that function itself. However, in .NET 4, you can use the dynamic keyword to cause the runtime to select the correct overload dynamically based on T at runtime, which is what you are looking to happen.
Simple example:
class Main {
static void somefunction(System.String str)
{
System.Console.WriteLine("In String overload");
}
static void somefunction(System.Object obj)
{
System.Console.WriteLine("In Object overload");
}
static void somegenericfunction<T>(T object)
{
somefunction(object);
}
static void dynamicfunction<T>(dynamic T object)
{
somefunction(object);
}
static void main(System.String[] args)
{
somegenericfunction("A string"); // Calls Object overload, even though it's a String.
dynamicfunction("A string"); // Calls String overload
}
}
Note that I don't actually have my compiler on hand and this might not compile literally, but close enough.

implicit or explicit conversion from T to T[]

Is there a way to implement a generic implicit or explicit converter for anything to an array of anything, something like this:
public static implicit operator T[](T objToConvert)
{
return new T[] { objToConvert };
}
No. The closest I can think of is an extension method:
public static T[] AsArray<T>(this T instance)
{
return new T[]{instance};
}
Use as:
var myArray = myInstnace.AsArray();
Note that you can omit the type name from the array constructor, which means the syntax is fairly clean, even with a long type name:
ReallyLongAndAwkwardTypeName value;
MethodThatTakesArray(new[] {value});
Operator overloading methods have to live inside the class they are overriding operators for (one side or the other). Since "T" is not defined, I don't see how this can be accomplished.
You can do it using normal method:
public static T[] ToArray<T>(T objToConvert) {
return new T[] { objToConvert };
}
I don't think you can define generics operator. Note, anyway, that the compiler is sufficient cleaver to guess the type of the generic param, so you can use:
var aString="";
var aStringArray=ToArray(aString);
aStringArray is defined as a string array even if you don't specify the generic param.
I was trying to think of situations where you might really use an implicit conversion to array. I started to wonder if many of the situations where you would want to do this could be alleviated by use of the params keyword.
The main situation that I could think of was that you had a single item of something and wanted to pass it to a function that takes an array as a parameter:
static void Main(string[] args)
{
string x = "I'm just a poor variable. Nobody loves me.";
Stickler.IOnlyTakeArrays_Rawr111(x); // won't go in! square peg, round hole, etc.
// *sigh* fine.
Stickler.IOnlyTakeArrays_Rawr111(new[] { x });
}
class Stickler
{
public static void IOnlyTakeArrays_Rawr111(string[] yum)
{
// ...
}
}
Hopefully in this situation the author of the method that you want to call has choosen to use the params keyword to allow you to pass your variable without wrapping it in an array:
class DataConcierge
{
public static T Create<T>(int id)
{
// ...
}
public static void Save<T>(params T[] items)
{
// ...
}
}
static void Main(string[] args)
{
var customer = DataConcierge.Create<Customer>(123);
// ...
DataConcierge.Save(customer); // this works!
//----------------------------------------------------
// or
//----------------------------------------------------
var customers = new Customer[]
{
DataConcierge.Create<Customer>(123),
DataConcierge.Create<Customer>(234),
DataConcierge.Create<Customer>(345),
};
// ...
DataConcierge.Save(customers); // this works too!
}
Of course, this doesn't really help you in situations where you need convert a variable to a single item array but not as a parameter to a method or in situations where the author of the method didn't use the params keyword.
But what kind of situation would the former be? Assigning an array to a property? Psh. How often does that happen?
And the latter? If the author didn't use the params keyword when they could have, then send them an email complaining about it. If the author is yourself, feel free to be extra belligerent in the email.
Hopefully you can tell that I'm being facetious. Seriously, though, are there any other common usage situations that you can think of where the params keyword would not be applicable?
** Disclaimer: I don't advocate excessive use of the params keyword. Use it if you think you should, but don't take my post to mean that you should always use the params keyword whenever you can.
In the past I've used the concept of a "Conductor" (my own name for it), which is just a class/struct that provides access to an underlying value.
The concept is useful for abstracting the access to a particular value retrieved from somewhere. For example, if you wanted to abstract access to a particular value in a dictionary, you could create a Conductor object that held a reference to the dictionary and the appropriate key for that value. You can also use this concept to easily implement rollback for serializable classes or for value types, though for that you'd need to add Rollback and Commit methods to the Conductor class/struct.
Below is an example of how you can use implicit conversions from T to Conductor and from Conductor to T[] in order to (sort of) achieve what you want.
static void Main(string[] args)
{
// implicit conversion here from Customer to Conductor<Customer>
Conductor<Customer> conductor = DataConcierge.Create<Customer>(123);
if (conductor.HasValue)
{
Console.WriteLine("I got a customer with Id {0}!", conductor.Value.Id);
// implicit conversion here from Conductor<Customer> to Customer[]
DataConcierge.Save<Customer>(conductor);
}
}
public struct Conductor<T> : IConductor<T>, IEquatable<T>, IEquatable<Conductor<T>>, IEquatable<IConductor<T>>
{
private T _Value;
public Conductor(T value)
{
this._Value = value;
}
public T Value
{
get { return this._Value; }
set { this._Value = value; }
}
public bool HasValue
{
get { return this._Value != null; }
}
public T GetValueOrDefault()
{
if (this.HasValue)
return this.Value;
else
return default(T);
}
public T GetValueOrDefault(T #default)
{
if (this.HasValue)
return this.Value;
else
return #default;
}
public bool TryGetValue(out T value)
{
if (this.HasValue)
{
value = this.Value;
return true;
}
else
{
value = default(T);
return false;
}
}
public T[] AsArray()
{
return new T[] { this._Value };
}
public static implicit operator Conductor<T>(T value)
{
return new Conductor<T>(value);
}
public static implicit operator T(Conductor<T> conductor)
{
return conductor.Value;
}
public static implicit operator T[](Conductor<T> conductor)
{
return conductor.AsArray();
}
public bool Equals(T other)
{
var otherEquatable = other as IEquatable<T>;
if (otherEquatable != null)
return otherEquatable.Equals(this.Value);
else
return object.Equals(this.Value, other);
}
public bool Equals(Conductor<T> other)
{
if (other.HasValue)
return this.Equals(other.Value);
else
return !this.HasValue;
}
public bool Equals(IConductor<T> other)
{
if (other != null && other.HasValue)
return this.Equals(other.Value);
else
return !this.HasValue;
}
public override bool Equals(object obj)
{
if (obj == null)
return !this.HasValue;
var conductor = obj as IConductor<T>;
if (conductor != null)
{
if (conductor.HasValue)
return this.Equals(conductor.Value);
else
return !this.HasValue;
}
return object.Equals(this.Value, obj);
}
public override int GetHashCode()
{
if (this.HasValue)
return this.Value.GetHashCode();
else
return 0;
}
public override string ToString()
{
if (this.HasValue)
return this.Value.ToString();
else
return null;
}
}

How do I override the equals operator == for an interface in C#?

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.

Categories

Resources