The method of casting a base type to a derivative type

I'm not sure if this is a strange thing or not, or if it is some kind of code smell ... but I was wondering if there is a way (some kind of oop pattern would be nice) to "pour" the base type into the form of its derivative type. I know that this makes little sense, since the derived type will have additional functionality that the parent does not offer, which in itself does not have a fundamentally correct sound. But is there a way to do this? Here is a sample code, so I can better explain what I ask.

public class SomeBaseClass { public string GetBaseClassName {get;set;} public bool BooleanEvaluator {get;set;} } public class SomeDerivedClass : SomeBaseClass { public void Insert(SqlConnection connection) { //...random connection stuff cmd.Parameters["IsItTrue"].Value = this.BooleanEvalutar; //... } } public static void Main(object[] args) { SomeBaseClass baseClass = new SomeBaseClass(); SomeDerivedClass derClass = (SomeDerivedClass)baseClass; derClass.Insert(new sqlConnection()); } 

I know this seems silly, but is there a way to do something like this?

+43
inheritance c # oop design-patterns
Sep 23 '08 at 22:32
source share
17 answers

Not bad, in "managed" languages. This is an omission, and there is no sensible way to deal with it, precisely for the reason that you have described (subclasses provide more than base classes - where does this come from "more"?). If you really want similar behavior for a specific hierarchy, you can use constructors for derived types that will use the base type as a prototype.

You could build something with a reflection that handled simple cases (more specific types that don't have an add state). In general, just redesign to avoid the problem.

Edit: Woops, cannot write conversion operators between base / derived types. Strangeness Microsoft is trying to "protect you" from yourself. Ah, well, at least they are not like the sun, like the sun.

+30
Sep 23 '08 at 22:37
source share

Try composition instead of inheritance!

It seems to me that you are better off passing an instance of SomeBaseClass to SomeDerivedClass (which will no longer output the base class and should be renamed as such)

 public class BooleanHolder{ public bool BooleanEvaluator {get;set;} } public class DatabaseInserter{ BooleanHolder holder; public DatabaseInserter(BooleanHolder holder){ this.holder = holder; } public void Insert(SqlConnection connection) { ...random connection stuff cmd.Parameters["IsItTrue"].Value = holder.BooleanEvalutar; ... } } public static void Main(object[] args) { BooleanHolder h = new BooleanHolder(); DatabaseInserter derClass = new DatabaseInserter(h); derClass.Insert(new sqlConnection); } 

Check out http://www.javaworld.com/javaworld/jw-11-1998/jw-11-techniques.html (page 3):

Reusing code with composition Composition provides an alternative way for Apple to reuse peeling (). Instead of distributing fruit, Apple may contain a link to the fruit instance and define its own peel () method, which simply calls peel () on Fruit.

+17
Sep 24 '08 at 0:15
source share

Personally, I don’t think it is worth using Inheritance in this case. Instead, just pass an instance of the base class in the constructor and access it through a member variable.

 private class ExtendedClass //: BaseClass - like to inherit but can't { public readonly BaseClass bc = null; public ExtendedClass(BaseClass b) { this.bc = b; } public int ExtendedProperty { get { } } } 
+15
Sep 26
source share

Downcasting makes sense if you have an object of a derived class, but it refers to a reference of the type of the base class, and for some reason you want references to the derived type to refer to it. In other words, you can lower to change the effect of the previous increase. But you cannot have an object of a base class referenced by a type reference of a derived class.

+9
Sep 23 '08 at 22:46
source share

I am not saying I recommend this. But you can turn the base class into a JSON string and then convert it to a derived class.

 SomeDerivedClass layer = JsonConvert.DeserializeObject<SomeDerivedClass>(JsonConvert.SerializeObject(BaseClassObject)); 
+7
May 01 '12 at 21:02
source share

No, It is Immpossible. In a managed language like C #, this just won't work. Runtime will not allow this, even if the compiler skips it.

You yourself said it seemed stupid:

 SomeBaseClass class = new SomeBaseClass(); SomeDerivedClass derClass = (SomeDerivedClass)class; 

So ask yourself, is there a class instance of SomeDerivedClass ? No, therefore, the conversion does not make sense. If you need to convert SomeBaseClass to SomeDerivedClass , then you must provide some kind of conversion, either a constructor or a conversion method.

It sounds as if your class hierarchy needs some work. In general, it should not be possible to convert an instance of a base class into an instance of a derived class. Usually there should be data and / or functionality that does not belong to the base class. If the functionality of a derived class is applied to all instances of the base class, then it must either be collapsed into the base class or be part of a new class that is not part of the base class hierarchy.

+5
Sep 23 '08 at 22:53
source share

C # language does not allow such statements, but you can still write them down and they work:

 [System.Runtime.CompilerServices.SpecialName] public static Derived op_Implicit(Base a) { ... } [System.Runtime.CompilerServices.SpecialName] public static Derived op_Explicit(Base a) { ... } 
+5
Apr 13 '13 at 12:17
source share

Yes - this is the smell of code, and to a large extent eliminates the fact that the inheritance chain is damaged.

My guess (from a limited example) is that you would prefer DerivedClass to work with an instance of SomeBaseClass, so that "DerivedClass has SomeBaseClass" rather than "DerivedClass is SomeBaseClass". This is known as the “preferred composition over inheritance”.

+1
Sep 23 '08 at 23:14
source share

As others have noted, the casting that you offer is actually impossible. Maybe this could be the case when you can enter a Decorator pattern (Head First extract)?

+1
Jan 12 '09 at 11:22
source share

Have you thought about an interface to implement your base class and your derived class? I do not know the specifics of why you implement this method, but it can work.

+1
Oct 19 '09 at 14:54
source share

This will not work. Go to the help page related to the compilation error.

The best solution is to use factory methods here.

0
Sep 23 '08 at 22:37
source share

This is called downcasting, and Seldaek’s suggestion to use the “safe” version sounds.

Here's a pretty decent description with code samples .

0
Sep 23 '08 at 22:39
source share

This is impossible, because how are you going to get the "extra" that the derived class has. How does the compiler know that you mean the derived class1, not the derivedClass2 when you create it?

I think you are really looking for a factory pattern or similar, so that you can create objects without knowing the explicit type that is being created. In your example, the Insert method will be the interface that returns the factory instance.

0
Sep 23 '08 at 23:01
source share

I don’t know why no one said this, and I might have missed something, but you can use the as keyword and if you need to use the if statement if.

 SomeDerivedClass derClass = class as SomeDerivedClass; //derClass is null if it isnt SomeDerivedClass if(class is SomeDerivedClass) ; 

-edit- I asked this question a long time ago

0
Jan 14 '10 at 20:27
source share

Recently, I needed to extend a simple DTO with a derived type to add a few more properties to it. Then I wanted to reuse some of the conversion logic that I used, from internal database types to DTO.

How I solved this was a forced empty DTO class constructor, using it as follows:

 class InternalDbType { public string Name { get; set; } public DateTime Date { get; set; } // Many more properties here... } class SimpleDTO { public string Name { get; set; } // Many more properties here... } class ComplexDTO : SimpleDTO { public string Date { get; set; } } static class InternalDbTypeExtensions { public static TDto ToDto<TDto>(this InternalDbType obj) where TDto : SimpleDTO, new() { var dto = new TDto { Name = obj.Name } } } 

Then I can reuse the conversion logic from simple DTO when converting to complex. Of course, I will have to fill out properties of a complex type in some other way, but with many, many properties of a simple DTO, this really simplifies IMO things.

0
Mar 13 2018-12-12T00:
source share

Like many answers, you cannot downgrade, which makes full sense.

However, in your case, SomeDerivedClass does not have properties that will be missing. Thus, you can create an extension method as follows:

 public static T ToDerived<T>(this SomeBaseClass baseClass) where T:SomeBaseClass, new() { return new T() { BooleanEvaluator = baseClass.BooleanEvaluator, GetBaseClassName = baseClass.GetBaseClassName }; } 

So, you are not casting, just convert:

 SomeBaseClass b = new SomeBaseClass(); SomeDerivedClass c = b.ToDerived<SomeDerivedClass>(); 

This really only works if all the data in the base class is in the form of readable and writable properties.

0
Aug 21 '14 at 9:21
source share

C ++ handles it with a constructor. C ++ Typecasting . It seems to me that this is an oversight. Many of you have raised the question of what a process with additional properties will do. I would answer what the compiler does when it creates a derived class, when the programmer does not set properties? I dealt with this situation similar to C ++. I create a constructor that accepts a base class, and then manually sets the properties in the constructor. It is definitely preferable to set a variable in a derived class and break inheritance. I would also select it according to the factory method, because I think the resulting code will be cleaner.

-one
Jan 24 '12 at 16:22
source share



All Articles