Can I use generic objects as variables then cast them upon construction?

Say I have created the following library of functions:

public class MyClassFloat {
   float foo;
   float bar;
   function MyClassFloat() {}
   function UpdateBar() {
      bar = foo * 2.0f;
   }
}
public class MyClassVector3 {
   Vector3 foo;
   Vector3 bar;
   function MyClassVector3() {}
   function UpdateBar() {
      bar = Vector3.Scale( foo, new Vector3(2.0f,2.0f,2.0f) );
   }
}

And so on, with Vector2 and Quaternion. Can I instead do:

enum What( Float, Vector3 )
public class MyClass {
   What what;
   object foo;
   object bar;
   function MyClass( What w ) {
      what = w;
      if (w==What.Float) {
         foo = float foo; // not sure of syntax to cast an object as a new type?
         bar = float bar;
      }
      else if (w==What.Vector3) {
         foo = new Vector3 foo;
         bar = new Vector3 bar;
      }
   }
   function UpdateBar() {
      if (what==What.Float) {
         bar = foo * 2.0f;
      }
      else if (what==What.Vector3) {
         bar = Vector3.Scale( foo, new Vector3(2.0f,2.0f,2.0f) );
      }
   }
}

… in order to put them all into one generic class?

You can, yes, with some caveats.

First of all, float is not itself a subclass of Object. System.Single, however, is. All primitive “value types” such as float have “reference type” versions, which inherit from Object and can be the subject of casting. These are known as “boxed” values.

Boxed values are immutable. You create one with, say, new Single(1.5f), and the returned object will always be equal to 1.5. If you want to change the value later, you do that by creating a new Single and assigning it to the same variable. Different object, different quantity, same variable.

C# has a lot of automatic support for boxing and unboxing values, such that you can assign them directly from value types (with the creation happening automatically, behind the scenes), and even implicitly cast from Object to value types (with the typechecking happening behind the scenes).

More info is available here.

Also, you don’t really need the what member variable; you can just directly check the types of the objects that foo and bar point to.

Incidentally, though, a whole lot of the stuff you’re doing there seems like it might be better handled by generics. What is your specific application here? You can do what you want to do the way you’re doing it here (more or less), but you’ll end up doing a whoooole lotta boilerplate code. There are most likely more straightforward

Ben 12’s answer above has provided me with a direction to head in, but I’ve encountered one problem I can’t figure out:

public class Smooth<SM> {
	public SM target;
    public Smooth() {}
    public void Inc(float i) {
       if (target.GetType().FullName=="System.Single") {
          target++;
       }
       else if (target.GetType().FullName=="UnityEngine.Vector3") {
          target.x++;
       }
    }
}

The above (which I want to be able to instantiate as a float or a vector3) results in the following compile error:

error CS1061: Type SM' does not contain a definition for x’ and no extension method x' of type SM’ could be found (are you missing a using directive or an assembly reference?)