如何在c#中使用对象初始化和类

本文关键字:对象 初始化 | 更新日期: 2023-09-27 18:10:28

我有一个class

  class TestFixture
    {
        public string a { get; set; }
        public int b { get; set; }
        public int c { get; set; }
        public string d { get; set; }
        public string e { get ; set ; }
        public int f { get; set; }
        public int g { get; set; }
        public bool h { get; set; }
        public string i { get; set; }
        public bool j { get; set; }
        public bool k { get; set; }
        public TestFixture()
        {
            e= dosomething(a, b);
            f= false;
            g = DateTime.Now.ToString("yyMMddhhmmss");
            h= TestName.Equals("1") && b.Equals("2") ? 1000 : 1;
            i= 10000000;
            j= a.Equals("FOT");
            k = false;
        }
    }

我想定义新的TestFixture为SO

new TestFixture { a = "", b = 1, c=2, d="" };

,而其余的属性应该在构造函数中自动定义。

如何在c#中使用对象初始化和类

是的,这是可能的。使用对象初始化式不会跳过调用构造函数。

TestFixture fixture = new TestFixture() // or just new TestFixture { ... }
{
    a = "", 
    b = 1, 
    c = 2, 
    d = "" 
};

这将调用您定义的构造函数,然后在对象初始化器中设置a, b, cd


在构造函数中弹出一个断点并运行调试器。这将告诉你代码中的东西是如何以及何时被调用的。

Visual Studio中的调试


重构:

public class TestFixture
{
    public string a { get; set; }
    public int b { get; set; }
    public int c { get; set; }
    public string d { get; set; }
    // dosomething should check for null strings
    public string e { get { return dosomething(a, b); } }
    public int f { get; set; }
    public int g { get; set; }
    public bool h 
    {
        get { return TestName.Equals("1") && b.Equals("2") ? 1000 : 1; }
    }
    public string i { get; set; }
    public bool j { get { return a != null && a.Equals("FOT"); } }
    public bool k { get; set; }
    public TestFixture(string a, int b, int c, string d) 
        : this() 
    {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
    public TestFixture()
    {
        f = false;
        g = DateTime.Now.ToString("yyMMddhhmmss");
        i = 10000000;
        k = false;
    }
}

@hunter的答案是正确的,你可以使用对象初始化语法,这些属性将在构造函数运行后设置。但是,我想指出您的代码中可能存在的一些缺陷

public TestFixture()
{
    e= dosomething(a, b);
    f= false;
    g = DateTime.Now.ToString("yyMMddhhmmss");
    h= TestName.Equals("1") && b.Equals("2") ? 1000 : 1;
    i= 10000000;
    j= a.Equals("FOT");
    k = false;
}

此代码不设置ab,但您有依赖于它们的值(e, g, j)的东西。对象初始化语法不是在这里有用,如果构造函数中的其他值依赖于这些值,则必须为这些值设置适当的默认值。

例如,当您写入var obj = new Bar() { A = "foo" };时,它将展开为

var obj = new Bar(); // constructor runs 
obj.A = "Foo"; // a is set 

显然,构造函数中查看A的代码不会看到值"Foo"。如果您需要来查看这个值,对象初始化策略将无法提供帮助。您需要一个构造函数重载,它接受要存储在A中的值。

var obj = new Bar("Foo");

如果我理解对了,您希望在构造函数运行之前用给定的值初始化a, b, c和d属性。不幸的是,这样做是不可能的,因为默认构造函数总是在对象初始化函数之前运行。我建议你这样做:

class TestFixture
{
    //... properties
    public TestFixture()
    {
        this.init();
    }
    public TestFixture(string a, int b, int c, string d)
    {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
        this.init();
    }
    private void init()
    {
        e= dosomething(a, b);
        f= false;
        g = DateTime.Now.ToString("yyMMddhhmmss");
        h= TestName.Equals("1") && b.Equals("2") ? 1000 : 1;
        i= 10000000;
        j= a.Equals("FOT");
        k = false;
    }
}

这样你就可以在其他初始化代码运行之前初始化a, b, c和d属性。