質問

I have some background in the python initializer (essentially Python object constructor syntax), and the syntax to instantiate an object in Python is as follows:

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

Why is it, in C#, I have to provide defaults in the body of the constructor method, when in python I can declare them as optional, and default values are passed in (see the __init__'s signature):

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

Why can't I do the following in 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; 
    }

Is it possible to have constructor syntax in C# that is similar (if not an exact duplicate) to Python's initializer syntax?

役に立ちましたか?

解決

This has been done using Named and Optional Arguments (C# Programming Guide)

Visual C# 2010 introduces named and optional arguments. Named arguments enable you to specify an argument for a particular parameter by associating the argument with the parameter's name rather than with the parameter's position in the parameter list. Optional arguments enable you to omit arguments for some parameters. Both techniques can be used with methods, indexers, constructors, and delegates.

The definition of a method, constructor, indexer, or delegate can specify that its parameters are required or that they are optional. Any call must provide arguments for all required parameters, but can omit arguments for optional parameters.

Each optional parameter has a default value as part of its definition. If no argument is sent for that parameter, the default value is used.

他のヒント

You should look into Constructor Chaining. Basically boils down to constructors calling other constructors to avoid duplicate code.

I program in C# and Python, so here's a view from someone who recently went from C# to Python:

C# provides a default constructor if you do not create one.

So, by default (if you didn't have a constructor already), you could instantiate the object with its defaults like follows:

var Account = new Account();

This would instantiate those properties with their respective default values.

If you provide a constructor, you must then provide the default constructor as well (if you intend on constructing an object just by: var account = new Account();:

public Account() {} //default constructor

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

The other primitive types in your class are initialized according to their default values.

If you'd like something Pythonic, you need to be sure you're using C# 4.0; we call them Optional Parameters. Their usage (in your case) would be exactly as you wrote it:

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

A few style comments:

  • In C#, we use properties. They aren't used quite the same way in Python, and in Python you'd be more likely to use fields. Our properties are PascalCased.

  • We don't use 'in' and 'out' parameters as part of the parameter name (there's no need to, we have ref and out for when we need to pass references -- sadly something that is missing from Python (although not really sad because it makes code more complex)).

  • In C#, fields are Camel cased -- or camelCased, as it were. In Python, they'd follow Unix conventions: first_name as opposed to firstName.

  • In C#, your properties are public by default, and they should be. In Python, everyone assumes public, private is only assumed if an underscore precedes the variable -- not so in C#.

If you want a more short hand approach you can use the object initializer.

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

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

As of VS2010 (I believe C# 4.0) C# does allow named and optional parameters similar to how you use them in Python.

Unfortunately, older versions of C# don't have this (I think somewhat due to C#'s Java legacy, but this is just speculation on my part).

C# allows you also to utilize object initializers:

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 }

You can that way specify dynamically which fields you want to initialize.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top