1

我在 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__'s 签名):

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 的初始化程序语法类似(如果不是完全重复)的构造函数语法?

4

6 回答 6

7

这是使用命名和可选参数完成的(C# 编程指南)

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

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

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

于 2013-08-19T19:20:57.410 回答
5

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

于 2013-08-19T19:20:15.370 回答
3

我用 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;我们称它们为可选参数。它们的用法(在您的情况下)将与您所写的完全相同:

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' 参数作为参数名称的一部分(没有必要,当我们需要传递引用时,我们有ref和for —— 遗憾的是 Python 中缺少的东西(虽然不是很伤心,因为out它使代码更复杂))。

  • 在 C# 中,字段是 Camel 大小写的 - 或camelCased, 实际上。在 Python 中,它们遵循 Unix 约定:first_name而不是 firstName。

  • 在 C# 中,您的属性是public默认的,它们应该是。在 Python 中,每个人都假设public,private仅在变量前面有下划线时才被假设——在 C# 中不是这样。

于 2013-08-19T19:22:28.690 回答
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" };
于 2013-08-19T19:22:44.450 回答
0

从 VS2010(我相信 C# 4.0)开始,C# 确实允许命名参数和可选参数,类似于在 Python 中使用它们的方式。

不幸的是,旧版本的 C# 没有这个(我认为在某种程度上是由于 C# 的 Java 遗留问题,但这只是我的猜测)。

于 2013-08-19T19:24:24.320 回答
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 }

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

于 2013-08-19T19:26:27.557 回答