如何使C#构造函数语法更加pythonic?

时间:2013-08-19 19:16:03

标签: c# python constructor default-constructor object-initialization

我在python初始化程序中有一些背景知识(本质上是Python对象构造函数语法),在Python中实例化对象的语法如下:

class Account:
     def __init__(self,name=None,address="Not Supplied",balance=0.0):
         this.name = name
         this.address=address
         this.balance=balance

为什么在C#中,我必须在构造函数方法的主体中提供默认值,在python中我可以将它们声明为可选,并传入默认值(请参阅__init__的签名):

public class Account
{
    private string name; 
    private string address;
    private decimal balance;

    public Account (string inName, string inAddress, decimal inBalance)
    { 
        name = inName; 
        address = inAddress; 
        balance = inBalance; 
    }

    public Account (string inName, string inAddress) 
    {
        name = inName; 
        address = inAddress;
        balance = 0;
    } 

    public Account (string inName) 
    { 
        name = inName;
        address = "Not Supplied";
        balance = 0;
    }
}

为什么我不能在C#中执行以下操作?

public class Account
{
    private string name; 
    private string address;
    private decimal balance;

    public Account (string inName, string inAddress="not supplied", decimal inBalance=0;)
    { 
        name = inName; 
        address = inAddress; 
        balance = inBalance; 
    }

是否有可能在C#中使用与Python的初始化语法类似(如果不是完全重复)的构造函数语法?

6 个答案:

答案 0 :(得分:6)

这是使用Named and Optional Arguments (C# Programming Guide)

完成的
  

Visual C#2010引入了命名和可选参数。命名   arguments允许您为特定参数指定参数   通过将参数与参数的名称相关联而不是与   参数在参数列表中的位置。 可选参数   使您可以省略某些参数的参数。这两种技术   可以与方法,索引器,构造函数和委托一起使用。

     

方法,构造函数,索引器或委托的定义可以   指定其参数是必需的或它们是可选的。   任何调用都必须为所有必需参数提供参数,但可以   省略可选参数的参数。

     

每个可选参数都有一个默认值作为其定义的一部分。   如果没有为该参数发送参数,则使用默认值。

答案 1 :(得分:4)

你应该研究Constructor Chaining。基本上归结为构造函数调用其他构造函数以避免重复代码。

答案 2 :(得分:2)

我使用C#和Python编程,所以这里是最近从C#到Python的人的观点:

如果您不创建默认构造函数,C#将提供默认构造函数。

因此,默认情况下(如果您还没有构造函数),您可以使用以下默认值实例化对象:

var Account = new Account();

这将使用各自的默认值来实例化这些属性。

如果你提供了一个构造函数,那么你必须提供默认的构造函数(如果你想构建一个对象只需:var account = new Account();

public Account() {} //default constructor

public Account(string name)
{
    Name = name;
}

您班级中的其他原始类型将根据其默认值进行初始化。

如果你想要Pythonic,你需要确保你使用的是C#4.0; we call them Optional Parameters。它们的使用(在您的情况下)将与您编写的完全相同:

public string Name { get; set;} 
public string Address {get; set;}
public decimal Balance {get; set;}

public Account (string name, string address="not supplied", decimal balance=0;)
{ 
    Name = name; 
    Address = address; 
    Balance = balance; 
}

一些风格评论:

  • 在C#中,我们使用属性。它们在Python中的使用方式并不完全相同,而在Python中,您更有可能使用字段。我们的房产是PascalCased。

  • 我们不使用'in'和'out'参数作为参数名称的一部分(我们需要传递refout时不需要引用 - 遗憾的是Python中缺少的东西(虽然不是很难过,因为它使代码更复杂))。

  • 在C#中,字段是Camel cased - 或camelCased,就像它一样。在Python中,他们遵循Unix约定:first_name而不是firstName。

  • 在C#中,您的属性默认为public,它们应该是。{在Python中,每个人都假定publicprivate仅在下划线位于变量之前时才会被假定 - 在C#中不是这样。

答案 3 :(得分:0)

如果您想要更简洁的方法,可以使用对象初始值设定项。

public class Account
{
   public string Name { get; set; } 
   public string Address { get; set; } 
   public decimal Balance { get; set; } 
}

var account = new Account { Name = "Dave" };

答案 4 :(得分:0)

从VS2010开始(我相信C#4.0)C#允许named and optional parameters类似于在Python中使用它们的方式。

不幸的是,旧版本的C#没有这个(我认为有些原因是由于C#的Java遗留问题,但这只是我的猜测。)

答案 5 :(得分:0)

C#还允许您使用对象初始值设定项:

public class Account
{
    public string name { get; set;} 
    public string address { get; set;} 
    public decimal balance { get; set;} 
}

Account acc = new Account () { name="Some Name", address="Some Address", balance=10.0 }

您可以通过这种方式动态指定要初始化的字段。