C #: data type conversion at runtime

This is my first time I used StackOverflow. I have found many answers to many of my questions here before, and so I thought that I would try to ask something myself.

I am working on a small project and now I am a bit stuck. I know how to solve my problem - just not the way I want it to be solved.

The project includes an NBT analyzer, which I decided to write myself, since it will be used for more or less custom NBT file variants, although the basic principle is the same: a binary data stream with predefined "keywords" for certain types of tags. I decided to try to make one class only for all types of tags, since the structure of the tags is very similar - they all contain type and payload. And here I am stuck. I want the payload to have a specific type, which, when an explicit conversion is done implicitly, throws an error.

The best I can come up with is to do a payload like Object or dynamic, but that will allow all the conversions to be 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 to do this? I would like to solve this, somehow tell C # that from now on, although Payload is dynamic, it throws an exception if the assigned value cannot be implicitly converted to the type of the current value - unless, of course, this is done explicitly.

I am open to other ways of doing 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 still ugly ... // this is ok } else if(...) { ... // this is not ok, throw an exception } ... ... ... } } 
+6
source share
2 answers

Have you considered using generics? This will automatically give you the opportunity to check the compilation time by 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"); 
+3
source

If you know you need Int64, why not use Convert.ToInt64?

0
source

Source: https://habr.com/ru/post/894002/


All Articles