C# - Chain Calling of Constructor

痞子三分冷 提交于 2020-01-13 05:17:48

问题


I'm currently studying C# and I'm learning about constructors and the chain calling of constructors so as not to have to paste the same code (the same value for variables) in each constructor.

I have three constructors, one with no parameters, one with three parameters and one with four parameters. What I'm looking to do is, use the default constructor to call the constructor with three parameters, passing default values for the parameters (variables) and the constructor that has three parameters, I'm looking for that to call the constructor with four parameters. I seem to have the first one sorted listing the default values but I'm struggling how to write the constructor with three parameters and then get this to call the constructor with four parameters if required.

The default constructor should assign all instance variables of the type string to string.Empty.

public Address()
{
   m_street = string.Empty;
   m_city = string.Empty;
   m_zipCode = string.Empty;
   m_strErrMessage = string.Empty;
   m_country = Countries;
}


public Address(string street, string city, string zip)
{
}

public Address(string street, string city, string zip, Countries country)
{
}

I was looking to do the following but it doesn't work:-

public Address(string street, string city, string zip)
     : this street, string.Empty, city, string.Empty, zip, string.Empty
{
}

回答1:


The idea would be to leave the logic of the instantiation to the constructor that takes in the most parameters and use the others as methods that only pass values to that constructor, that way you only write the code once.

Try this:

public Address() 
  : this(String.Empty, String.Empty, String.Empty)
{
}


public Address(string street, string city, string zip) 
  : this(street, city, zip, null)
{
}

public Address(string street, string city, string zip, Countries country) 
{
    m_street = street;
    m_city = city;
    m_zipCode = zip;
    m_country = Countries;
    m_strErrMessage = string.Empty;
}



回答2:


You should generally chain the constructor with the least information onto the one with the most information, not the other way round. That way each field can be assigned in precisely one place: the constructor with the most information. You've actually described that behaviour in your post - but then your code does something entirely different.

You also need to use the right syntax for constructor chaining, which is:

: this(arguments)

For example:

public class Address
{
    private string m_street;
    private string m_city;
    private string m_zipCode;
    private string m_country;

    public Address() : this("", "", "")
    {
    }


    public Address(string street, string city, string zip)
        : this(street, city, zip, "")
    {
    }

    public Address(string street, string city, string zip, string country)
    {
        m_street = street;
        m_city = city;
        m_zip = zip;
        m_country = country;
    }
}

For more information on constructor chaining, see this article I wrote a while ago.




回答3:


You need ():

public Address(string street, string city, string zip)
      : this(street, string.Empty, city, string.Empty, zip, string.Empty)
{
}

This will call the Address constuctor with 3 of 6 args specified (if there is one), is that what you are trying to do?




回答4:


Your syntax is close. Try this

public Address(string street, string city, string zip)
      : this( street, string.Empty, city, string.Empty, zip, string.Empty )
{
}

In your example you should also remove the default constructor and put the initialization of the variables into the constructor that is at the end of the chain. That one being the one that takes a country in your example.

Hope this helps.




回答5:


You can use this to call other constructors on the same object. The general idea is to do the actual initialisation of properties/fields in the most complex constructor and chain progressively simpler ones together giving default values.

Assuming Countries is an Enum, such as:

public enum Countries
{
   NotSet = 0,
   UK,
   US
}

You can do this(Note that your enum doesnt have to have a Default state such as NotSet, but if it doesnt, you just need to decide what the default is if the value is not specified):

public Address()
  :this(String.Empty,String.Empty,String.Empty)
{        
}

public Address(string street, string city, string zip)
  :this(street,city,zip,Countries.NotSet)
{
}

public Address(string street, string city, string zip, Countries country) 
{ 
    m_street = street;
    m_city = city
    m_zipCode = zip;
    m_country = country;
}



回答6:


You need parenthesis for the constructor chaining, like so:

public Address(string street, string city, string zip)
          : this (street, string.Empty, city, string.Empty, zip, string.Empty)
    {
    }

Also, you are calling a constructor with 6 parameters.



来源:https://stackoverflow.com/questions/6944729/c-sharp-chain-calling-of-constructor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!