Fanon

I did a search on the subject, and the answer I found said that converting a base class to a derived class is not possible. I find this answer to be unsatisfactory, and I wish to make sure that it is indeed the correct answer.

I am writing some code (obviously), and in my code, I have a base class and an inherited class of that base class. There are times I wish to convert the base class to the inherited class. According to section 13.2.3 of the C# specification, this is possible:

"From any class-type S to any class-type T, provided S is a base class of T."

There's also evidence that in the .NET Framework that it's possible (converting WebRequest to HttpWebRequest and Control to TextBox). So why is it I get a runtime error of InvalidCastException when I attempt to explicitly cast an instance of my base class to an instance of a derived class of that base class



Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

IsshouFuuraibou

There is a difference between (the two conxepts), only one of them is possible.

It is possible to store a child as it's parent (ie TextBox can be stored in Control). This is fundamental, you can see it in Exceptions most clearly as you can catch Exception and catch everything that has some inheritance line to Exception. You can store a derived class into a base class object and then (cast) back to the derived class. However you couldn't store a TextBox in a Control object then cast it to a Label (also derived from Control).

Converting from base to derived (parent to child, or part to product) is impossible to do "directly". It would be akin to being able to convert from a molecule from an atom object. Molecule is a "derived" class from atom (or let's just say it is). However, Molecule has more information than what atom provides, how do you deal with this The problem is that derived classes have knowledge of their base but the base has no knowledge of their derived classes.

[edit]I originally used boxing, it was the wrong terminology. Let's try not to confuse anyone with poorly worded replies being left.[/edit]





Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Peter Ritchie

IsshouFuuraibou wrote:
This is called boxing and unboxing. You can always store into a base class and then unbox out to the derived class.
No, boxing and unboxing is the packaging and unpackaging of value types as reference types. This is due to Object being a reference type.

[edit]see http://msdn2.microsoft.com/en-us/library/aa691157(VS.71).aspx [/edit]






Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Peter Ritchie

Fanon wrote:

I did a search on the subject, and the answer I found said that converting a base class to a derived class is not possible. I find this answer to be unsatisfactory, and I wish to make sure that it is indeed the correct answer.

I am writing some code (obviously), and in my code, I have a base class and an inherited class of that base class. There are times I wish to convert the base class to the inherited class. According to section 13.2.3 of the C# specification, this is possible:

"From any class-type S to any class-type T, provided S is a base class of T."

There's also evidence that in the .NET Framework that it's possible (converting WebRequest to HttpWebRequest and Control to TextBox). So why is it I get a runtime error of InvalidCastException when I attempt to explicitly cast an instance of my base class to an instance of a derived class of that base class

You can't convert an instance of a base class to a derived class without some sort of conversion operator. If you have a instance of a derived class stored as a base class variable you can cast as a derived class. For example:

Code Snippet

Base base = new Derived();

Derived derived = base as Derived;






Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

IsshouFuuraibou

thanks for clarifying that, I was sure I was using the wrong wording...

now is there a wording for storing a derived class stored as a base class variable, or is that the only description of it I thought there was some terminology for that.





Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Peter Ritchie

IsshouFuuraibou wrote:
thanks for clarifying that, I was sure I was using the wrong wording...

now is there a wording for storing a derived class stored as a base class variable, or is that the only description of it I thought there was some terminology for that.
I consider it part of inheritance. Depending on the context, polymorphic may apply.




Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Fanon

Peter Ritchie wrote:
You can't convert an instance of a base class to a derived class without some sort of conversion operator. If you have a instance of a derived class stored as a base class variable you can cast as a derived class. For example:

Code Snippet

Base base = new Derived();

Derived derived = base as Derived;

Thank you for that information. I did not know you could program specific operators. I did a quick search and found I can program my own implicit and/or explicit conversion operators. Thank you so much!





Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Fanon

*sigh*

So I write an explicit operator, and now I get a compile error saying "User-defined conversions to values of a base class are not allowed; you do not need such an operator". Well apparently I do because I can't convert it!

Here's my code:

Code Snippet

public DerivedClass(BaseClass b) {

//code to do the conversion

}

public static explicit operator DerivedClass(BaseClass b) {

DerivedClass temp = new DerivedClass(b);

return temp;

}





Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Peter Ritchie

I'm checking into why that specific conversion is an error. I think it might be a bug; but, I'll confirm. If it's a bug there probably won't be a fix for it until .NET 3.x.

So, you'll have to write a non-operator method, e.g.:

Code Snippet
internal static Derived FromBase(Base b)
{
Derived result = b as Derived;
if(null == result)
{
result = new Derived(b);
}
return result;
}

Note that since a reference to Derived can be cast to Base this method first checks to see if the object is already a Derived object; if not it creates a new one.






Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Fanon

That is what I have resorted to to make the code work, although your method is more complete (checking to see if the object was cast to its base first).

Thanks again, Mr. Ritchie.





Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Peter Ritchie

Okay, found the official word from Microsoft: http://forums.microsoft.com/MSDN/ShowPost.aspx PostID=142939&SiteID=1

Looks like you're stuck writing a non-operator method.






Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Samodaje

Hi,

i solved the problem using reflection:

class Base
{
private string title;
public string Title
{
get...
set..
}

public CopyTo(ref Object target)
{
Type sourceType = this.GetType();
Type destinationType = destination.GetType();

foreach (PropertyInfo sourceProperty in sourceType.GetProperties())
{
PropertyInfo destinationProperty = destinationType.GetProperty(sourceProperty.Name);
if (destinationProperty != null)
{
destinationProperty.SetValue(destination, sourceProperty.GetValue(this, null), null);
}
}
}
}

class Inherited : Base
{
//Inherits Title from base
...
}


main()
{
Base baseObject = new Base();
Inherited inheritedObject = new Inherited();
Object obj = (Object)inheritedObject;

baseObject.Title = "Hello";
baseObject.CopyTo(ref obj);

System.Console.WriteLine(inheritedObject.Title);

}

-------------------------------------------------------
Function CopyTo will copy values from source class to destination for properties with same name in source and destination.
Hope this helps,
Regards







Re: Visual C# Language Explicit Conversion of Base Class to Derived Class

Thomas Danecker

This is no "correct" solution in terms of class design. I do not advocate this to anyone. It does e.g. not check the type of the property nor is it anyhow performant.

It has its sense that there is no easy way to cast a base class to a concret class or to a sibling (which would be the same as casting one sibling to its base and then to another concret implementation of the base - it's sibling).

The objects are not compatible and just copying the properties doesn't make them really compatible.

If you know that they are compatible, you can create a new method which converts them (this method could also be an explicit casting operator), but you should not provide a general-purpose solution because ther is no such general-purpose solution also the "solution" provided by Samodaje may work by some very rare problems but there will always be a better, more performant and nicer alternative to it.