Corner case in using lambdas expression in base constructor

后端 未结 5 1523
伪装坚强ぢ
伪装坚强ぢ 2021-01-05 08:03

In the Framework we are building we need the following pattern:

public class BaseRenderer
{
    Func renderer;
    public BaseRenderer(Func<         


        
相关标签:
5条回答
  • 2021-01-05 08:26

    wouldn't : base(()=>this) be legal? You can do : this() so a reference to this seems to be fine, just not properties on it. The fact that : base(()=>this) is no longer legal just broke some partial function application I did during construction. Can be fixed by moving it into the body of the constructor, but there is an order difference: the base class can no longer be passed transparently a partial function application to itself (because the base class constructor gets called before the body of the subclass constructor).

    0 讨论(0)
  • 2021-01-05 08:27

    As asgerhallas correctly points out, this should not be legal according to the specification. We accidentally allowed this bogus usage to sneak by the error detector that searches for incorrect usages of "this" before it is legal to do so. I've fixed the bug; the C# 4 compiler correctly flags your program as an error.

    Many apologies for the inconvenience; this was my mistake.

    0 讨论(0)
  • 2021-01-05 08:41

    The C# specification at 7.5.7 says: "A this-access is permitted only in the block of an instance constructor, an instance method, or an instance accessor."

    And even more directly in 10.11.1: "An instance constructor initializer cannot access the instance being created. Therefore it is a compile-time error to reference this in an argument expression of the constructor initializer, as is it a compile-time error for an argument expression to reference any instance member through a simple-name."

    Though the instance has been created according to 7.5.10.

    Hmm. That's actually pretty strange. I did not see any compile-time error.

    0 讨论(0)
  • 2021-01-05 08:43

    The lambda captured the value of "this" and captured null since the object wasn't constructed yet. This strikes me as a compiler bug, it should have generated an error for this. Code like this normally generates a CS0027 (keyword 'this' is not available in the current context) or CS0120 (an object reference is required). I bet that isn't easy to implement.

    Anyhoo, the code cannot work. The NameRenderer class needs a constructor with a string argument so it can initialize the base class.

    0 讨论(0)
  • 2021-01-05 08:45

    I think you are right. The subclass is not yet constructed when the base class constructor is called and therefore accessing members on the subclass gives you a null reference. CLR doesn't have a way to know at compile time if the instance exists or not.

    Moving the logic to the constructor body should fix the problem.

    0 讨论(0)
提交回复
热议问题