Reputation: 11904
public class Derived : BaseClass
{
public Derived(string name) : base(name) {}
public static implicit operator BaseClass(Derived derived)
{
return new BaseClass(derived.ColorHex);
}
public static implicit operator Derived(BaseClass baseclass)
{
return new Derived(baseclass.name);
}
}
This won't work. why isn't it allowed?
I can potentially write the logic necessary for it to make sense, especially when converting from the base to the derived one.
EDIT:Changed the title of the question
Upvotes: 8
Views: 8584
Reputation: 71
I had the need to be able to create a derived object from a base object in order to capture additional information that the base class did not have. For my purposes, construction a derived object with all the fields copied from the base object was acceptable. I used AutoMapper to make my life a bit easier:
class AnnotatedAlert : Alert
{
public string Color;
// I don't know why C# doesn't allow user defined conversions from a base class
// so I am creating a conversion constructor instead
public AnnotatedAlert(Alert from)
{
AutoMapper.Mapper.Map(from, this);
}
static AnnotatedAlert()
{
AutoMapper.Mapper.CreateMap<Alert, AnnotatedAlert>();
}
};
Upvotes: 0
Reputation: 81347
There is a general rule that the result of casting an object to its own type is the original object. If a storage location of type BaseType
holds an instance of DerivedType
, casting from the original type to DerivedType
should tell the compiler to use DerivedType
's members, but shouldn't actually "do" anything to the object. If custom base-to-derived conversion operators were allowed, it would be necessary to either: (1) Have a cast-to-instance's own-type operation sometimes yield a new object and sometimes not, or (2) Have a derived type object which is stored in a base-type storage location behave substantially differently from a base-type or unrelated-type object, without clearly visible type-checking code that would make it do so. While there are times one might want to have a method which, given a base-type parameter, might return a new derived-type object or--if given an instance of the derived type, simply return it unmodified, it is generally better to have such a thing "look" like a method instead of a typecast.
BTW, there is one situation where a compiler could allow user-defined type conversions between a "base type" and a "derived type" without the above ambiguity: when one of the types is a struct. Although C# pretends that value types inherit from ValueType
, every value type definition really defines two things: a heap object type which derives from ValueType
, and a collection of storage locations, which isn't an object and doesn't derive from anything. C# defines an implicit casting operator from the latter type to the former, and an explicit casting operator from the former to the latter. Since conversion between a heap object and a collection of storage locations is never reference preserving, allowing user-defined conversion operators to be used in such context would not cause muddled inheritance semantics. The only difficulty with such conversion would be the fact that value types which used them would either be unusable as generic types, or would lose their special behavior if passed as generic types.
Upvotes: 1
Reputation: 437904
Because there is already an implicit conversion from Derived
to BaseClass
, and the converse does not make any sense.
Regarding the latter: if your Base
objects are meant to be implicitly convertible to Derived
-- why aren't they Derived
objects in the first place?
Obligatory quotes from the standard:
6.1.6 Implicit reference conversions
The implicit reference conversions are:
- [...]
- From any class-type S to any class-type T, provided S is derived from T.
This says there's an implicit conversion Derived
=> Base
, as we all know.
6.2.4 Explicit reference conversions
The explicit reference conversions are:
- [...]
- From any class-type S to any class-type T, provided S is a base class of T.
- [...]
This says there's already an explicit conversion Base
=> Derived
(which is what allows you to try downcasting at runtime).
6.4.1 Permitted user-defined conversions
C# permits only certain user-defined conversions to be declared. In particular, it is not possible to redefine an already existing implicit or explicit conversion.
And this says that since the two conversions of interest are already defined by the language, you can't redefine them.
Upvotes: 10
Reputation: 6524
To synthesize you can already cast a Derived object into a BaseClass object without writing any code :
BaseClass baseClass = new BaseClass("");
Derived derived = new Derived("");
baseClass = (BaseClass)derived;
But you can't rewrite the cast from Derived to BaseClass.
For the other cast, from BaseClass to Derived, it doesn't make so much sense.
In conclusion you can redefine the cast only if there is no inheritance relation between the 2 classes.
Upvotes: 1
Reputation: 35156
Because it would disturb the symanitcs of polymorphism.
Upvotes: 1