在基类中拥有子内容

时间:2011-09-09 16:31:33

标签: c# .net asp.net

我尝试使用基类作为不同子类内容的容器。依赖于执行流,基类的对象将分配其子类之一的类类型。像这样:

  BaseClass B = new ChildClass(). 

问题是我无法访问子类功能的内容。请参阅下面的示例。我在两行中得到了编译错误:

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

编译器声称Address不包含Street或Address1的定义。

根本不可能做我喜欢的事情吗? 你能告诉我一种获得这种功能的方法吗?

我花了很多时间在一些网站上搜索解释。但到目前为止还没有成功。我很感激在这个问题上提供任何帮助。

实施例

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 = "";
}

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"
    }
}

6 个答案:

答案 0 :(得分:1)

您需要将其用作子类类型,目前您将其视为BaseClass

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

问题在于Contact Address属性不是AddressDK,只有Address类型没有Street属性

您可以通过创建方式来解决此问题

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

答案 1 :(得分:0)

应该如下 ((AddressDK)Contact.Address).Street = "First line in foreign address"

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

答案 2 :(得分:0)

Contact.Address是一个Address对象,因此它没有成员 - 事实上它确实被分配给派生对象AddressDK左右并不重要。

所以你需要修改代码:

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;
    }
}

但是为了使它有用,你需要在基类中有一些(通常)虚拟定义的功能。一个例子可以是打印地址:

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

然后在不同的子类中实现打印出适用的字段。

此外,还有一种在C#中初始化对象的好方法:

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

......但这与上述情况完全相同。

答案 3 :(得分:0)

看看我的解决方案。首先使用特定的地址类,并将其分配给您的通用地址持有者。

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 = "";
    }



}

答案 4 :(得分:0)

您的地址类不包含任何属性,因此代码无效。要正确使用继承地址,需要在基层实施“Street”,“HouseNumber”,“Address1”,“Address2”等。

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

但是,这只会解决(无双关语)AddressDK属性。为了使您的代码快速运行,请将所有国际属性也放在地址类中。

答案 5 :(得分:0)

如果您使用的是VS 2010,则可以使用dynamic类型。

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

这将允许您编译以下内容:

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"
}

但是,如果没有重新分配,您将无法访问这两个属性:

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

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