Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Permanently cast derived class to base

Class A { } Class B : A { }  B ItemB = new B(); A ItemA = (A)B;  Console.WriteLine(ItemA.GetType().FullName); 

Is it possible to do something like above and have the compiler print out type A instead of type B. Basically, is it possible to permanently cast an object so it "loses" all the derived data?

like image 492
Telavian Avatar asked Feb 18 '11 22:02

Telavian


People also ask

Can we assign derived class object to base?

In C++, a derived class object can be assigned to a base class object, but the other way is not possible.

How can we get derived class from base class?

If you're trying to get the base class name, it'd be something like: Type classType = typeof(YourClass); Type baseType = classType. BaseType; string baseClassName = baseType.Name; Note that, if you recursively search the base types, when you call BaseType on typeof(System.

Can base class access derived class properties?

No, you cannot access any derived class members using base class pointer even pointing to a derived class instance. However you can access those values though methods of derived class.

What is base class method?

A base class access is permitted only in a constructor, an instance method, or an instance property accessor. It is an error to use the base keyword from within a static method. The base class that is accessed is the base class specified in the class declaration.


2 Answers

What you ask for is impossible for two reasons:

  1. ItemA.GetType() does not return the compile-time type of the variable ItemA - it returns the run-time type of the object referred to by ItemA.
  2. There's no way you could make (A)B result in a representation-changing conversion (i.e. a new A object) because user-defined conversion operators (your only hope here) cannot convert from derived to base-classes. You're just going to get a normal, safe, reference-conversion.

That aside, what you ask for is very strange; one would think you're trying really hard to violate Liskov's substiution principle. There's almost certainly a serious design-flaw here that you should address.

If you still want to do this; you could write a method that manually constructs an A from a B by newing up an A and then copying data over. This might exist as a ToA() instance-method on B.

If you characterized this problem as "How do I construct an A from an existing A?", it makes a lot more sense: create a copy-constructor on A, whose declaration looks like public A(A a){...}, which is agnostic to subclass-specific details. This gives you a general means to create an A from an existing instance of A or one of its subclasses.

like image 194
Ani Avatar answered Oct 13 '22 10:10

Ani


I've recently run into this migrating an old project to Entity Framework. As it was mentioned, if you have a derived type from an entity, you can't store it, only the base type. The solution was an extension method with reflection.

    public static T ForceType<T>(this object o)     {         T res;         res = Activator.CreateInstance<T>();          Type x = o.GetType();         Type y = res.GetType();          foreach (var destinationProp in y.GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))         {             var sourceProp = x.GetProperty(destinationProp.Name);             if (sourceProp != null)             {                 destinationProp.SetValue(res, sourceProp.GetValue(o));             }         }          return res;     } 

It's not too neat, so use this if you really have no other option.

like image 32
Nite Avatar answered Oct 13 '22 12:10

Nite