stklik
stklik

Reputation: 844

C# overloading: method for null value

I am currently writing a serializer for some of my classes. I created a set of static methods with the following signatures

public static string serialize(int val);
public static string serialize(string val);
public static string serialize(float val);
public static string serialize(MyOwnClass val);
public static string serialize(AnotherClass val);
public static string serialize(SomethingElse val);

Additionally, sometimes I have to deal with null values. I would like to treat them in a special way, i.e. a signature like:

public static string serialize(null val);

The call to the function should be something like:

string s = serialize(someVariableThatMightBeNull);

And it should be triggered anytime serialize is called with the value null, independent of which type the variable was declared with.

Is there any way to implement this in C#?

Currently my only solution would be to add this line to each method: (for datatypes that can be null):

if(val == null){ dealWithNull(); }

This solution seems a bit tedious, as I have about 30 different cases and I would prefer not having a dispatch method.


As an example, Xtend features dispatch methods that also offer the Void type which checks for null values. Xtend Dispatch Methods

Upvotes: 3

Views: 2298

Answers (4)

LOST
LOST

Reputation: 3249

So I've got a similar problem, except your workaround was not suitable for me, as I needed a different return type on the null overload. E.g. I needed Tensor == Tensor to return Tensor<bool>, and Tensor == null to return simply bool.

The way I solved it was the following trick, that works under the following assumptions:

  1. Tensor is the most specific class, and is generally not supposed to be inherited.
  2. There are no overloads of == with the second operand of reference type other than Tensor.

If that is the case, then you can simply define class NullTensor: Tensor, that can not be instantiated (private constructor only), and have overloads

  • Tensor == NullTensor -> bool
  • Tensor == Tensor -> Tensor

Then if you write (Tensor)x == null, the first overload would be picked over the second one, as null can be either Tensor or NullTensor, but the second type is more specific.

Upvotes: 0

Johan Boul&#233;
Johan Boul&#233;

Reputation: 2090

Your current solution is the only one in C# (where you don't have true templates).

I think you might just be happy about it as long as the size of the boilerplate code stays small compared to the rest of the serialization code.

If it's acceptable for you to introduce a tight-coupling between your classes and the serialization code, then you can go the "OO" way to eliminate redundancy by introducing a base class that handles nulls and have each derived class override a virtual implementation method.

Upvotes: 0

Dave
Dave

Reputation: 483

The method that will be called depends on the type of the thing that is being passed in.

If you have something typed as string that holds a null, then it's going to hit the method with the string parameter. If you have something that's a MyOwnClass type variable and it's null, then it's going to hit the method with the MyOwnClass parameter.

I think your best option is to do something in the code that's external to this.

if(whatever == null) { serializeNull(whatever); } else { serialize(whatever); }

Upvotes: 2

Irwene
Irwene

Reputation: 3035

If I understood you correctly :

I'd go with a method signature waiting for an object.

The compiler will ALWAYS choose the method signature that seem the closest to what you used. So it will only use the method with the object signature if no other are available.

In this method, you will be able to check if the parameter is null and/or handle classes that does not have their own static method for serialization


For custom serialization, IMHO, I think it would be better to let each class handle themselves.

In order to do this, I'd define an Interface ICustomSerialization containing a method string CustomSerialization()

I'd then make each one of the classes I'd need to serialize inherit from this interface and implement the the method inside each class.

That would offer the benefit of having the serialization code IN the related class, avoid a massive serialization class.

Allow your serializer to work with interface (and thus not having to know how to handle each particular class)

Upvotes: 3

Related Questions