简体   繁体   中英

Cast derived class to another derived in c#

I have a base class :

interface IBaseClass{
     int x;
     int y;
     baseClass someMethod();
}

and some derived class :

class dClass1 : IBaseClass {
     int x;
     int y;
     baseClass someMethod();
}
class dClass2 : IBaseClass {
     int x;
     int y;
     baseClass someMethod();
}

The value of property according to the subclass algorithm is different from other subclass now i want cast these subclass to them:

dClass1 c1=new dClass1 ();
c1.x=4;
c1.y=5;
dClass2 c2=c1;//cast to dClass2 , but value of property set by  according to the own algorithm  
Console.WriteLine("{0}, {1}", c1.x, c1.y);//4,5
Console.WriteLine("{0}, {1}", c2.x, c2.y);//7,1

dClass1 and dClass2 are two different types . You can't directly cast one to the other. You'd have to convert one to the other. For example:

dClass1 c1 = new dClass1
{
    x=4,
    y=5
};
dClass2 c2 = new dClass2
{
    x = c1.x,
    y = c1.y
};

Or, using multiple lines like your original code:

dClass1 c1 = new dClass1();
c1.x=4;
c1.y=5;
dClass2 c2 = new dClass2();
c2.x = c1.x;
c2.y = c1.y;

The point is, the system has no way to directly cast one type to another type. You can encapsulate this conversion into factory methods on either type, or on separate classes. But casting isn't an option. Just because the two types have members of the same type/name/etc. doesn't make them the same type.

First off, lets make it clear that IBaseClass is not a base class, its an interface , which is something quite different. Pointing out the differences is not in the scope of this answer but you can easily read about it, starting here .

That said, as others have stated, you can't do what you want directly. Consider the canonical example IAnimal , Dog , Cat , etc. Evey dog and every cat are animals, but cats are not dogs and dogs are not cats and you are basically asking a cat to be a dog; you first need to teach cats how to dogify (they won't do that out of the box for you).

In order to achieve this behavior there are quite a few ways how you can do it:

  1. User defined cast: You can define operators that convert from one class to another. If you make them implicit you'd even get your code to compile as it is right now:

     public static implicit operator dClass2(dClass1 obj) { //logic to convert obj to corresponding new dClass2 instance } 

    Now this would be legal:

     var c1 = new dClass1(); dClass2 c2 = c1; // implicit cast operator is called. 

    Note that if you were to implement the cast operator as explicit, the former code would not compile. You would need to explicitly cast c1 :

     var c2 = (dClass2)c1; 
  2. Define a dClass2 constructor that takes a dClass1 argument:

     public dClass2(dClass1 obj) { ... } 

    and you'd write the following code:

     var c1 = new dClass1(); var c2 = new dClass2(c1); 
  3. Define a static factory method in dClass2 that takes a dClass1 argument and produces a new dClass2 instance:

     public static dClass2 CreateFrom(dClass1 obj) { ... } 

    And the corresponding code:

     var c1 = new dClass1(); var c2 = dClass2.CreateFrom(c1); 
  4. Many more I haven't bothered to think about...

Which one you choose is up to personal taste. I'd probably use the explicit cast, but there is nothing inherently wrong with any of the options available.

What you're trying to do isn't possible. You can cast an object to a less (or more in some cases) derived type, but you can't cast an object to another type unless you define a custom cast on the type.

You can read about defining custom casts here: https://msdn.microsoft.com/en-us/library/ms173105.aspx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM