Reputation: 844
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
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:
Tensor
is the most specific class, and is generally not supposed
to be inherited.==
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
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
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
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