Snik
Snik

Reputation: 171

Why would a C# instance constructor have a different name from the returned type?

I sometimes see in C# code:

An instance being created, that then invokes a constructor that is not the same as that of the type.

For example:

Person somebody = new Member();

What possible cases would this show up in, and why is it desirable?

(I thought it had to do with calling a base class constructor but I couldn't get that to compile)

Upvotes: 1

Views: 207

Answers (4)

Jeppe Stig Nielsen
Jeppe Stig Nielsen

Reputation: 61982

Your question is not really a question about constructors. It is all about implicit conversions. In your declaration:

Person somebody = new Member();

the right-hand side of the = operator clearly has (compile-time) type Member. However the variable somebody has (compile-time) type Person. That is legal only if there exists an implicit conversion from Member to Person. Then the code is really like Person somebody = (Person)(new Member()); except that the "cast" is invisible.

Now, the most usual implicit conversion is the reference conversion from a class to its (direct or indirect) base class, or to an interface that it implements.

There is a somewhat different implicit conversion, a boxing conversion from a struct or enum to its base class or interface.

There are also user-defined implicit conversions which are like a kind of methods (written with implicit operator).

There are more implicit conversions, for example from a value type V to the Nullable<> version of it, usually written as V?, but it would be strange if Person was just a using alias for Member?, so this one is not realistic in your example. Another one that is rarely relevat in this example, is "widening" conversion from e.g. int to long.

Read the C# Language Specification to learn more about what conversions exist.

Upvotes: 1

ProgrammingLlama
ProgrammingLlama

Reputation: 38785

Member inherits from Person or Person is a poorly named Interface and Member implements it:

More on inheritance: http://msdn.microsoft.com/en-gb/library/ms173149(v=vs.80).aspx http://en.wikipedia.org/wiki/Inheritance_(object-oriented_programming)

More on interfaces: http://msdn.microsoft.com/en-us/library/ms173156.aspx http://en.wikipedia.org/wiki/Protocol_(object-oriented_programming)

You could define the following using inheritance:

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

public class Adult : Person
{
    public string Workplace { get; set; }
}

public class Child : Person
{
    public List<string> Toys { get; set; }
}

And then if you create an instance of Adult (Adult a = new Adult();) you will have access to the Name, DateOfBirth and Workplace properties. Likewise with the child, you will have the Toys property.

Furthermore, you can store a list of Person which contains both adults and children:

List<Person> people = new List<Person>();
people.Add(new Adult() { Name = "Adult", DateOfBirth = DateTime.Now, Workplace = "Microsoft" });
people.Add(new Child() { Name = "Child", DateOfBirth = DateTime.Now, Toys = new List<string> { "Car", "Train" } });

and then you can go through each printing out the name and date of birth:

foreach(Person p in people)
{
    Console.WriteLine(p.Name + ", " + p.DateOfBirth.ToString("dd/MMM/yy"));
    if(p is Child)
    {
        Console.WriteLine(p.Name + " has the following toys: " + string.Join(", ", ((Child)p).Toys));
    }
    else if(p is Adult)
    {
        Console.WriteLine(p.Name + " works at " + ((Adult)p).Workplace;
    }
}

Interfaces basically define a contract (i.e. an object that implements IPerson will provide implementations for its methods). It's like an ethernet card: there is a standard for how they talk to the network but how they work internally is up to the manufacturer as long as they provide the expected behaviour. Interfaces can't have any logic in them or store any data, they simply advertise what something implementing that interface provides.

public interface IPerson
{
    string Name { get; set; }
    DateTime DateOfBirth { get; set; }
}

public class Adult : IPerson
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    public string Workplace { get; set; }
}

public class Child : IPerson
{
    public string Name { get; set; }
    public DateTime DateOfBirth { get; set; }
    public List<string> Toys { get; set; }
}

There's also abstract classes which provide some of the functionality of interfaces but can implement some logic. The only thing to note in all of this is that a class can only be derived from (i.e. inherit from) a single class, although that class can inherit from another class. You can, however, implement multiple interfaces.

Upvotes: 3

Christian Phillips
Christian Phillips

Reputation: 18769

Member class probably looks like this...

public class Member : Person {}

Where Member derives from Person.

Upvotes: 0

T McKeown
T McKeown

Reputation: 12857

This is valid if Person is a Base class of Member

Similarly this is valid also:

Object o = new Member();

Upvotes: 2

Related Questions