There are two flaws to your request:
- the instance of
DerivedClass already IS and instance of the BaseClass so there is no need to convert it!
- Your
DerivedClass has not implemented the constructor overload with stuff parameter so there is no way for this class to access that constructor.
If the constructor is protected, then it can only be accessed via constructors in inherting classes or the base class itself, Normally we would use syntax like this when implementing a class and we want the specific base constructor to be called, but we only want internal logic to access it:
public sealed class DerivedClass : BaseClass
{
public DerivedClass ()
: base()
{
// the base implementation has been executed.
// now perform any other init logic you need.
}
private DerivedClass (List<int> stuff)
: base(stuff)
{
// the base implementation has been executed.
// now perform any other init logic you need.
}
// this is one way to access non-public constructors
public static DerivedClass CreateAnotherInstance(List<int> stuff)
{
return = new DerivedClass(stuff);
}
}
What you may not be aware of, and the reason that you don't need a Convert method at all is that and instance of DerivedClass IS an instance of BaseClass, the following statement is valid:
DerivedClass car = new DerivedClass();
BaseClass vehicle = car;
The following will also work if you are unsure if the base object was originally a specific derived implementation:
if (vehicle is DerivedClass derivedRef)
{
Console.Out.WriteLine("It was a DerivedClass instance all along");
}
else
{
Console.Out.WriteLine("Not a DerivedClass: " + vehicle.GetType().Name);
}
If your DerivedClass instance convert method returned a new instance of BaseClass then you would have to copy across all the neccessary properties and would lose the polymorphic abilities that Inheritance provides for our classes.
In regard to your update:
The reason I want to convert between the classes is the base class is "light" in that it contains no unmanaged code nor holds on resources. The derived class holds resources. When I am done with the derived class, but need to maintain the basic data, I want to convert to the base class.
I really can't understand why you would, that's not true, I understand your reasoning, I just don't think it is a good design, even to the point that i feel very strongly against providing an answer that will help you continue down this path... this type of pattern really doesn't need to use inheritance at all... with extreme caution, as in please do not do this:
public class BaseClass
{
protected readonly List<int> internalStuff;
public BaseClass()
{
internalStuff = new List<int>();
}
protected BaseClass(List<int> stuff)
{
internalStuff = new List<int>(stuff);
}
protected BaseClass CreateAsBase()
{
return new BaseClass(internalStuff);
}
// I see little point in allowing "stuff" to be passed through
// from the caller, this class already has access to the "stuff"
// but you've already demonstrated an unual taste for hard work
protected BaseClass CreateAsBase2(List<int> stuff)
{
return new BaseClass(stuff);
}
}
sealed class DerivedClass : BaseClass
{
public BaseClass ConvertToBaseClass()
{
return base.CreateAsBase();
...
// um, if you really need to, this is how you could pass the "stuff"
// I asusme you would only do this because you were going to modify
// it in a way that the base class could not anticipate.
return base.CreateAsBase2(aModifiedListOfInternalStuff);
}
}
Usually in cases like this, either there would be a Utility class or methods to handle the processing and intensive resource requirements, and you would pass around a reference to the DTO (Data Transfer Object) so you can discard the wrapper object, but the DTO would remain intact:
public class Vehicle
{
protected readonly List<int> internalStuff;
public Vehicle()
{
internalStuff = new List<int>();
}
protected Vehicle(List<int> stuff)
{
internalStuff = new List<int>(stuff);
}
public Color Color { get; set; }
}
public sealed class Car : Vehicle
{
public Car()
: base()
{
}
private Car(List<int> stuff)
: base(stuff)
{
}
public void AddOne()
{
internalStuff.Add(1);
}
}
// Wrapper that accepts a vehicle, and does "stuff" to it
public sealed class VehicleBusinessObjectWrapper : IDisposable
{
public Vehicle Vehicle { get; private set; }
public VehicleBusinessObjectWrapper(Vehicle dto)
{
Vehicle = dto;
}
public void ChangeColour(Color newColor)
{
Vehicle.Color = newColor;
/// you know, apply modifications to the Vehicle
}
public void Dispose()
{
// clean up your resources... if there are any
// for instance, deliberately clear the reference to the original DTO, just to prove a point
Vehicle = null;
// after this point, the Vehicle Object is still intact.
}
}
public static class BusinessLogic
{
public static void Test()
{
var originalCar = new Car();
using (var processor = new VehicleBusinessObjectWrapper(originalCar))
{
// We can still access the vehicle through the processor, we don't need inheritance
if (processor.Vehicle.Color != Color.Green)
processor.ChangeColour(Color.Green);
// do other stuff on the car, or on the vehicle...
if (processor.Vehicle is Car car)
{
car.AddOne();
}
}
// reference to wrapper is now gone, but our original car/vehicle still remains.
originalCar.ToString();
Vehicle v = originalCar;
Console.WriteLine(v == originalCar); // "True"
}
}
BaseClassand thats it.newBaseClassInstance = new BaseClass(internalStuff);is creating a new instance, and therefore you are externally trying to access the protected constructor. Even though it is in the derived class, it is external to the new instanceprotected, this modified access provide access only for base class and derived(s) class(es) only.protectedmembers on an object of typederived. Will answer more fully shortly