Home > Software engineering >  How to box VAR1 and unbox VAR2 according to the type of VAR1
How to box VAR1 and unbox VAR2 according to the type of VAR1

Time:08-27

Imagine having an integer

var aaa = (int)1; -------> here I have an int
var bbb = (object)aaa;-----> bbb is an object but the type is kept...
var ccc = aaa.GetType();---> ... in fact here I still have an integer

now I define a new variable

var ddd = (object)2;

and I want to cast it to the same type as aaa. ccc is a type and it's type integer but I can't do

var ddd = (ccc)2;

So what puzzles me is how to box a 1st variable and then unbox a 2nd variable according to the type of the 1st variable

Obiviously I did it here with int but the matter can be extended to whatever class type.

Thanks in advance

Patrick

CodePudding user response:

You cannot strongly type a variable at runtime. The advantage of a strong type (here int) versus a week type (object) is that you know at compile time (or design time) which members an object has and which operations you can apply to it. E.g., you know that you can write 5 * aaa if aaa is an int. You cannot do that with a string.

aaa.GetType() yields a System.Type object at runtime! You cannot use it to cast another object. Well, you could write something like

??? ddd = Convert.ChangeType(bbb, aaa.GetType());

but to what do you want to assign it? The type of ddd is unknown at compile time and the only possible type you can write in your code is object again. And btw., ChangeType returns an object. What else could it return?

Note that the var keyword does not help. var tells the compiler to infer the (strong) static type (which it does of course at compile time). If you hover the mouse over such a variable, the Visual Studio editor will reveal you the concrete type var stands for.

Generic types are always resolved at compile time. They do not help either.

With a limited number of possible types, you can use a switch expression or switch statement to do appropriate things depending on the type.

string message = bbb switch {
    string s   => $"bbb is the string '{s}' of length {s.Length}",
    int i      => $"10 times bbb is {10 * i}",
    DateTime d => $"bbb is {d:yyyy-MM-dd HH:mm:ss}",
    _          => "bbb has an unexpected type"
};

This uses type test patterns.


With class types this is a bit different. Here you can use Polymorphism. This works in a limited way with value types (structs) if they implement interfaces.

The idea behind polymorphism is that you do not need to know the concrete type of an object to do meaningful things with it. Example:

public abstract class Shape
{
    public abstract double Area();
}

public class Square : Shape
{
    public double SideLength { get; set; }

    public override double Area() => SideLength * SideLength;
}

public class Circle : Shape
{
    public double Radius { get; set; }

    public override double Area() => Math.PI * Radius * Radius;
}

Given these declarations, you can write:

private static void PrintArea(Shape shape)
{
    Console.WriteLine(shape.Area());
}

and

var shapes = new List<Shape> {
    new Circle { Radius = 4.5 },
    new Square { SideLength = 7.0 }
};

foreach (Shape shape in shapes) {
    PrintArea(shape);
}

You do not need to know what kind of shape you have, to determine its area. If you implement new shapes in future, the PrintArea method and the foreach-loop will not have to be adapted.

  • Related