开发者

Having child content in a base class

I try to use a base class as a container for different child class content. Dependent of the execution flow an object of the base class will be assign a class type of one of its child. Like this:

  BaseClass B = new ChildClass(). 

The problem is that I cannot get access to the content of the child classes features. Please see the example below. I get compilation error in the two lines:

  Contact.Address.Street = "MyStreat"
  Contact.Address.Address1 = "First line in foreign address"

The compiler claim that Address does not contain a definition for Street or Address1.

Is it not possible at all to do something like what what I try? Are you able to show me a way to get this kind of functionality?

I have used quite some time searching for an explanation on a number of the sites. But so far without success. I would appreciate any kind of help on this issue.

EXAMPLE:

public class Contact
{
    public string FirstName = "";开发者_JAVA百科
    public string LastName  = "";
    public string Country   = "DK";
    public Address Address  = null;
}

public class Address
{
}

public class AddressDK : Address
{
    public String Street      = "";
    public String HouseNumber = "";
    public string ZipCode     = "";
    public String City        = "";
}
public class AddressInternational : Address
{
    public string Address1 = "";
    public string Address2 = "";
    public string Address3 = "";
    public string Address4 = "";
    public string Address5 = "";
}

main()
{
    Contact Contact = new Contact();
    If (Contact.Country == "DK")
    {
        Contact.Address = new AddressDK();
        Contact.Address.Street = "MyStreat"
    }
    else
    {
        Contact.Address = new AddressInternational();
        Contact.Address.Address1 = "First line in foreign address"
    }
}


You need to use it as the child class type, currently you are treating it as a BaseClass

    Contact.Address = new AddressDK();
    ((AddressDK)Contact.Address).Street = "MyStreat"

The problem is that on Contact that Address Property isn't a AddressDK it's just the Address Type which doesn't have the Street property.

A way for you to solve this in the way your creating it would be to do

If (Contact.Country == "DK")
{
    new DKAddress = new AddressDK() { Street = "MyStreat"};
    Contact.Address = DKAddress;
}


If you are using VS 2010, you can use the dynamic type.

public class Contact
{
    public string FirstName = "";
    public string LastName = "";
    public string Country = "DK";
    public dynamic Address;
}

Which will allow you to compile the following:

Contact Contact = new Contact();
if (Contact.Country == "DK")
{
    Contact.Address = new AddressDK();
    Contact.Address.Street = "MyStreat"
}
else
{
    Contact.Address = new AddressInternational();
    Contact.Address.Address1 = "First line in foreign address"
}

However, you wouldn't be able to access both properties without reassignment:

Console.WriteLine( Contact.Address.Street ); // Prints "MyStreat"
Console.WriteLine( Contact.Address.Address1 ); // **RUNTIME ERROR!!!**

Here's a little light reading on the dynamic type.


It should be as following ((AddressDK)Contact.Address).Street = "First line in foreign address"

((AddressInternational)Contact.Address).Address1 = "First line in foreign address"


Contact.Address is an Address object and therefore it has no members - the fact that it really is assigned to a derived object AddressDK or so does not matter.

So you need to modify the code:

main()
{
    Contact Contact = new Contact();
    If (Contact.Country == "DK")
    {
        var address = new AddressDK();
        address = "MyStreat";
        Contract.Address = address;
    }
    else
    {
        var address = new AddressInternational();
        address = "First line in foreign address";
        Contact.Address = address;
    }
}

But for this to be useful you need to have some (often) virtually defined functionality in the base class. One example could be to print the address:

public abstract class Address
{
    public abstract void Print();
}

which then is implemented in the different subclasses in printing out the fields that apply.

Also, there is a nice way of initializing objects in C#:

Contact.Address = new AddressInternational { address = "First line..." };

... but that is really just the same as the above.


Take a look at my solution. Use the specific address class first and assign it to your generic Address holder.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Goffsoft2011
{
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Contact Contact = new Contact();
                Contact.Country = "DK";
                if (Contact.Country == "DK")
                {
                    AddressDK _address = new AddressDK();
                    _address.Street = "MyStreat";
                    Contact.Address = _address;

                }
                else
                {
                    AddressInternational _address = new AddressInternational();
                    _address.Address1 = "First line in foreign address";
                    Contact.Address = _address;
                }

                Console.WriteLine(((AddressDK)Contact.Address).Street);
                Console.ReadLine();
            }
            catch (Exception ex)
            {

            }

        }

    }

    public class Contact
    {
        public string FirstName = "";
        public string LastName = "";
        public string Country = "DK";
        public Address Address = null;
    }

    public class Address
    {
    }

    public class AddressDK : Address
    {
        public String Street = "";
        public String HouseNumber = "";
        public string ZipCode = "";
        public String City = "";
    }
    public class AddressInternational : Address
    {
        public string Address1 = "";
        public string Address2 = "";
        public string Address3 = "";
        public string Address4 = "";
        public string Address5 = "";
    }



}


Your Address class contains no properties, therefore the code will not work. To properly use inheritance Address would require "Street", "HouseNumber", "Address1", "Address2", etc. to be implemented at the base level.

public class Address
{
    public String Street      = "";
    public String HouseNumber = "";
    public string ZipCode     = "";
    public String City        = "";
}

However, this only addresses (no pun intended) the AddressDK properties. To get your code working quickly, put all the international properties in the Address class as well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜