Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# generics: cast generic type to value type

I have a generic class which saves value for the specified type T. The value can be an int, uint, double or float. Now I want to get the bytes of the value to encode it into an specific protocol. Therefore I want to use the method BitConverter.GetBytes() but unfortunately Bitconverter does not support generic types or undefined objects. That is why I want to cast the value and call the specific overload of GetBytes(). My Question: How can I cast a generic value to int, double or float? This doesn't work:

public class GenericClass<T>
    where T : struct
{
    T _value;

    public void SetValue(T value)
    {
        this._value = value;
    }

    public byte[] GetBytes()
    {
        //int x = (int)this._value;
        if(typeof(T) == typeof(int))
        {
            return BitConverter.GetBytes((int)this._value);
        }
        else if (typeof(T) == typeof(double))
        {
            return BitConverter.GetBytes((double)this._value);
        }
        else if (typeof(T) == typeof(float))
        {
            return BitConverter.GetBytes((float)this._value);
        }
    }
}

Is there a possibility to cast an generic value? Or is there another way to get the bytes?

like image 990
rittergig Avatar asked Apr 11 '13 21:04

rittergig


People also ask

What C is used for?

C programming language is a machine-independent programming language that is mainly used to create many types of applications and operating systems such as Windows, and other complicated programs such as the Oracle database, Git, Python interpreter, and games and is considered a programming foundation in the process of ...

Is C language easy?

Compared to other languages—like Java, PHP, or C#—C is a relatively simple language to learn for anyone just starting to learn computer programming because of its limited number of keywords.

What is C in C language?

What is C? C is a general-purpose programming language created by Dennis Ritchie at the Bell Laboratories in 1972. It is a very popular language, despite being old. C is strongly associated with UNIX, as it was developed to write the UNIX operating system.

What is the full name of C?

In the real sense it has no meaning or full form. It was developed by Dennis Ritchie and Ken Thompson at AT&T bell Lab. First, they used to call it as B language then later they made some improvement into it and renamed it as C and its superscript as C++ which was invented by Dr.


1 Answers

First off, this is a really bad code smell. Any time you're doing a type test on a type parameter like this odds are good you're abusing generics.

The C# compiler knows that you are abusing generics in this way and disallows the cast from the value of type T to int, etc. You can turn off the compiler getting in your way by casting the value to object before you cast it to int:

return BitConverter.GetBytes((int)(object)this._value);

Yuck. Again, it would be better to find another way to do this. For example:

public class NumericValue
{
    double value;
    enum SerializationType { Int, UInt, Double, Float };
    SerializationType serializationType;        

    public void SetValue(int value)
    {
        this.value = value;
        this.serializationType = SerializationType.Int
    }
    ... etc ...

    public byte[] GetBytes()
    {
        switch(this.serializationType)
        {
            case SerializationType.Int:
                return BitConverter.GetBytes((int)this.value);
            ... etc ...

No generics necessary. Reserve generics for situations that are actually generic. If you've written the code four times one for each kind of type, you haven't gained anything with generics.

like image 62
Eric Lippert Avatar answered Oct 18 '22 18:10

Eric Lippert