0

I have some old code from someone else that I need to fix so it builds again and one issue that I don't know how to fix, is constructor chaining. It looks something like this:

class Foo(){

  public Foo()
  {
    int i = /*block of code*/;
    this (i);
  }

  public Foo(int i)
  {
    //..
  }
}

The error comes at the this (i); line where it says Method, delegate, or event is expected. Basically it no longer allows you to use this as just a constructor anymore. Maybe it did in older version of C#.

What would be the appropriate way to fix this? I can replace public Foo() with public Foo(): this(i) but then it doesn't recognize the variable i anymore.

Graf123456
  • 91
  • 1
  • 1
  • 8
  • 2
    _"Basically it no longer allows you to use this as just a constructor anymore. Maybe it did in older version of C#."_ - **nope**, that has _never_ been a feature of C# (though I want it so badly). – Dai Sep 20 '22 at 12:44
  • 1
    _"What would be the appropriate way to fix this?"_ - you can't, at least, not like that, because the C# language does not let you run arbitrary code to mutate _instance state_ prior to calling the supertype's constructor. The CLR _does_ let you (as C# `record` types **do** have a reversed init order, in-fact) but C# does not currently expose this to users, which is super annoying. – Dai Sep 20 '22 at 12:45
  • The workaround is to have a static method that does the computation for `i`, then use `public Foo() : this(ComputeValue()) { ... }` – Jon Skeet Sep 20 '22 at 12:46
  • The only way the code could genuinely look like that is if it's the product of a decompiler that's using pseudo-syntax to represent something that's there on the IL level but not directly expressible in the language. – Jeroen Mostert Sep 20 '22 at 12:48

1 Answers1

0

If you want to run a block of code before calling this(), you can use a static method:

class Foo()
{
    public Foo() : this(SomeMethod())
    {
    }

    public Foo(int i)
    {
        //..
    }

    private static int SomeMethod()
    {
        int i = /*block of code*/;
        return i;
    }
}

Note that you can't mutate the instance state in SomeMethod(), but such logic should probably be in Foo(int i) anyway.

Johnathan Barclay
  • 18,599
  • 1
  • 22
  • 35