0

Here is my example:

public class Person
{
    public string Name { get; set; }
}

public class Client : Person
{
    public string LastName { get; set; }
}

public class Test
{
    Person p = new Person();
    Client c = (Client)p; //throws exception
}

Since Client inherits from Person, why i can't do this? if i can and this is the wrong way, how can i do it?

OBS: I am aware that the example above will do:

Person p = new Client();
Client c = (Client)p;
Jerry Stratton
  • 3,287
  • 1
  • 22
  • 30
Fabio Martins
  • 55
  • 2
  • 9

5 Answers5

5

Actually with a little detour, you could make such a conversion work, however, it requires an extra parent class for both other classes, and an implicit operator to turn a Client into a Person (though this might not be what you were originally after)

class Program
{
    public abstract class BasePerson
    {
        public string FirstName { get; set; }
    }

    public class Person : BasePerson
    {
    }

    public class Client : BasePerson
    {
        public string LastName { get; set; }

        public static implicit operator Client(Person p)
        {
            if (p == null)
            {
                return null;
            }
            return new Client { FirstName = p.FirstName };
        }
    }

    static void Main(string[] args)
    {
        Person p = new Person { FirstName = "Test" };
        Client c = (Client)p;
        Console.WriteLine(c.FirstName);
        Console.ReadLine();
    }
}

which would compile and offer the FirstName to a client, with a last name possibility, however, as i said, this might not be what you were after, just a possibility to make your code compile, and run with minimal changes...

UPDATE

As discussed in the comments, if i would need to implement such a conversion, i would prefer doing it by either

  • Creating a helper method

    public class Client : Person
    {
        public static Client GetClientFromPerson(Person p) 
        {
            if (p == null) 
            {
                return null;
            }
            return new Client { FirstName = p.FirstName };
        }
    }
    

which would result in:

Client c = Client.GetClientFromPerson(p);
  • Adding a second constructor

    public class Client : Person
    {
        public string LastName { get; set; }
    
        public Client()
        {
        }
    
        public Client(Person p) : this()
        {
            FirstName = p.FirstName;
        }
    }
    

which would result in:

Client c = new Client(p);

This would make reviewing the code by somebody else a lot easier, also possible maintenance in the future, and wouldn't require you to change the inheritance that you have now

Icepickle
  • 12,689
  • 3
  • 34
  • 48
  • But as per the problem Person is a parent class and client is the child class, what is the reason of introducing a new parent class BasePerson? – Nitin Aggarwal Jan 07 '15 at 00:11
  • @NitinAggarwal: it is necessary because otherwise you can also not compile, as you cannot make an implicit/explicit operator from or to a BaseClass. This was in essence just a trick to make it work, as i said, it might not have been what the OP was after, just a solution to make the code compilable + to enable the `(Client)p` statement – Icepickle Jan 07 '15 at 00:14
  • I appreciate your answer, i think what Fabio asked was different what you have answered, you have removed parent-child relationship between person and client. – Nitin Aggarwal Jan 07 '15 at 00:21
  • @NitinAggarwal I agree with you on that one, and i also mentioned it in the answer and in the comments, in his case i would choose to create rather a helper method like `Client GetClientFromPerson(Person p)`to make it clear to other persons that this isn't a cast and it is rather a conversion, or a constructor with public Client(Person p) but, i thought i would try thinking out of the box on this one :) – Icepickle Jan 07 '15 at 00:25
  • I would vote up but i don't have enough reputation yet. Hehe. – Fabio Martins Jan 07 '15 at 02:50
0

A Person is not a Client hence how do you expect the compiler to cast it? Try this and you will get a null assigned:

Client c = p as Client;

In other words: compiler error gone, but c will always be null.

Quality Catalyst
  • 6,531
  • 8
  • 38
  • 62
  • I thought that since Client inherits Person, when you try to cast the framework would do thejob of filling Client's Name property with the value of Person's Name Property. But its ok i got it, thanks for your time :D. – Fabio Martins Jan 06 '15 at 23:39
0

This throws an exception, because p is not a client. p has been created as person. You could create a client-object and cast it to its baseclass person, but not this way round.

Martin Tausch
  • 714
  • 5
  • 20
  • I thought that since Client inherits Person, when you try to cast the framework would do thejob of filling Client's Name property with the value of Person's Name Property. But its ok i got it, thanks for your time :D. – Fabio Martins Jan 06 '15 at 23:37
0

A child can inherit all the properties of its parent class, but parent can only inherit common properties. that does not means you can assign directly parent object to it's child object.

Nitin Aggarwal
  • 451
  • 1
  • 7
  • 18
0

you can do it by using as and is operatos.

By using as operator, if variable is not null then the class convertible to other class

Person p = new Person();
var conversionResultFromPersonToClient = p as Client;
if(conversionResultFromPersonToClient != null)
   //it means you can cast from person to client

Second way is using is operator

Person p = new Person();
Client c = new Client();
if(p is Client)
   //Then you can cast person to client
   c = (Client)p;
cimey
  • 189
  • 3
  • 10