How to work with object initialization and classes in C#

落花浮王杯 提交于 2020-01-16 19:09:08

问题


I have a 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;
        }
    }

I want to define new TestFixture as SO

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

while the rest of properties should be auto defined as it written in constructor.

Is it possible ?


回答1:


Yes, this is possible. Using an object initializer does not skip calling the constructor.

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

This will call the constructor you've defined and then set a, b, c, and d in your object initializer.


Pop a breakpoint in your constructor and run your debugger. This is should show you how and when things in your code are called.

Debugging in Visual Studio


Refactored:

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



回答2:


@hunter's answer is correct, you can use object initializer syntax, and those properties will be set after your constructor runs. However, I'd like to point out some flaws you may have with your code

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

This code does not set a or b, but you have things that depend on their values (e, g, j). Object initializer syntax is not going to be useful here, you have to have proper defaults for these values if other values in the constructor will depend upon them.

As an example, when you write var obj = new Bar() { A = "foo" };, that will expand to

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

Clearly, the code in the constructor that looks at A will not see the value "Foo". If you need it to see this value, object initialization strategy is not going to help. You need a constructor overload that takes the value to be stored in A.

var obj = new Bar("Foo");



回答3:


If I understand you right, you would like to the a, b, c and d properties to be initialized with the given values before the constructor runs. Unfortunately, that is not possible this way, because the default constructor always runs before the object intializers. I advise you to do something like this instead:

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

This way you can init the a, b, c and d properties before the other initializer code runs.



来源:https://stackoverflow.com/questions/7649568/how-to-work-with-object-initialization-and-classes-in-c-sharp

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