繁体   English   中英

在基类中包含子内容

[英]Having child content in a base class

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

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

您需要将其用作子类类型,当前您将其视为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;
}

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

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

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

……但实际上与上述相同。

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

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



}

您的Address类不包含任何属性,因此该代码将不起作用。 要正确使用继承地址,将需要在基本级别上实现“街道”,“房屋编号”,“地址1”,“地址2”等。

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

但是,这仅解决(没有双关语)AddressDK属性。 为了使您的代码快速工作,请将所有国际属性也都放入Address类。

如果使用的是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!!!**

这是有关动态类型的一些简要说明。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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