This is my first time using StackOverflow myself. I have found many answers to many of my question here before, and so I thought I would try asking something myself.
I'm working on a small project and I am a bit stuck right now. I know ways to solve my problem - just not the way I want it to be solved.
The project includes an NBT parser which I have decided to write myself since it will be used for a more or less custom variation of NBT files, though the core principle is the same: a stream of binary data with predefined "keywords" for specific kinds of tags. I have decided to try and make one class only for all the different types of tags since the structure of the tags are very similar - they all contain a type and a payload. And this is where I am stuck. I want the payload to have a specific type that, when an explicit conversion is done implicitly, throws an error.
The best I could come up with is to make the payload of type Object or dynamic but that will allow all conversions done implicitly:
Int64 L = 90000;
Int16 S = 90;
dynamic Payload; // Whatever is assigned to this next will be accepted
Payload = L; // This fine
Payload = S; // Still fine, a short can be implicitly converted to a long
Payload = "test"; // I want it to throw an exception here because the value assigned to Payload cannot be implicitly cast to Int64 (explicit casting is ok)
Is there any way of doing this? I would like to solve it by somehow telling C# that from now on, even though Payload is dynamic, it will throw an exception if the assigned value cannot be implicitly converted to the type of the current value - unless, of course, it is done explicitly.
I am open to other ways of accomplishing this, but I would like to avoid something like this:
public dynamic Payload
{
set
{
if(value is ... && Payload is ...) { // Using value.GetType() and Payload.GetType() doesn't make any difference for me, it's still ugly
... // this is ok
} else if(...) {
... // this is not ok, throw an exception
}
... ... ...
}
}
Have you considered using generics? This would automatically give you compile-time checking on which conversions are allowed.
class GenericTag<T>
{
public GenericTag(T payload)
{
this.Payload = payload;
}
public T Payload { set; get; }
}
// OK: no conversion required.
var tag2 = new GenericTag<Int64>(Int64.MaxValue);
// OK: implicit conversion takes place.
var tag1 = new GenericTag<Int64>(Int32.MaxValue);
// Compile error: cannot convert from long to int.
var tag4 = new GenericTag<Int32>(Int64.MaxValue);
// Compile error: cannot convert from string to long.
var tag3 = new GenericTag<Int64>("foo");
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With