Call one constructor from the body of another in C#

前端 未结 6 1769
情深已故
情深已故 2020-12-30 18:12

I need to call one constructor from the body of another one. How can I do that?

Basically

class foo {
    public foo (int x, int y)
    {
    }

             


        
相关标签:
6条回答
  • 2020-12-30 18:52

    this(x, y) is right, but it has to be before the start of the constructor body:

    public Foo(int x, int y)
    {
        ...
    }
    
    public Foo(string s) : this(5, 10)
    {
    }
    

    Note that:

    • You can only chain to one constructor, either this or base - that constructor can chain to another one, of course.
    • The constructor body executes after the chained constructor call. There is no way to execute the constructor body first.
    • You can't use this within the arguments to the other constructor, including calling instance methods - but you can call static methods.
    • Any instance variable initializers are executed before the chained call.

    I have a bit more information in my article about constructor chaining.

    0 讨论(0)
  • 2020-12-30 18:53

    You can't.

    You'll have to find a way to chain the constructors, as in:

    public foo (int x, int y) { }
    public foo (string s) : this(XFromString(s), YFromString(s)) { ... }
    

    or move your construction code into a common setup method, like this:

    public foo (int x, int y) { Setup(x, y); }
    public foo (string s)
    {
       // do stuff
       int x = XFromString(s);
       int y = YFromString(s);
       Setup(x, y);
    }
    
    public void Setup(int x, int y) { ... }
    
    0 讨论(0)
  • 2020-12-30 18:53

    This is not supported - see Constructors in C#.

    However, you can implement a common (private) method which you call from the different constructors...

    0 讨论(0)
  • 2020-12-30 18:55

    To call both base and this class constructor explicitly you need to use syntax given below (note, that in C# you can not use it to initialize fields like in C++):

    class foo
    {
        public foo (int x, int y)
        {
        }
    
        public foo (string s) : this(5, 6)
        {
            // ... do something
        }
    }
    

    //EDIT: Noticed, that you've used x,y in your sample. Of course, values given when invoking ctor such way can't rely on parameters of other constructor, they must be resolved other way (they do not need to be constants though as in edited code sample above). If x and y is computed from s, you can do it this way:

    public foo (string s) : this(GetX(s), GetY(s))
    
    0 讨论(0)
  • 2020-12-30 19:07

    There is a note in description of MethodBase.Invoke in MSDN

    If this method overload is used to invoke an instance constructor, the object supplied for obj is reinitialized; that is, all instance initializers are executed. The return value is null. If a class constructor is invoked, the class is reinitialized; that is, all class initializers are executed. The return value is null.

    I.e. you can get Constructor's method by reflection and call it through Invoke in your new constructor's body. But I haven't try it. And, of course, this solution have a lot of drawbacks.

    0 讨论(0)
  • 2020-12-30 19:12

    I've ran into this problem a time or two myself... I ended up having to extract whatever logic I needed in that other constructor into a private void method and calling it in both places.

    class foo
    {
      private void Initialize(int x, int y)
      {
        //... do stuff
      }
    
      public foo(int x, int y)
      {
        Initialize(x, y);
      }
    
      public foo(string s_
      {
        // ... do stuff
    
        Initialize(x, y)
        // ... more stuff
      }
    }
    
    0 讨论(0)
提交回复
热议问题