Reputation: 4835
I don't know if my understanding is wrong, but I am trying to do something like below:
I have a base class with two delegates:
public class Base
{
public Func<bool> Licensed { get; set; }
public Func<bool> Enabled { get; set; }
}
And a derived class as shown below:
public class Derived : Base
{
public int Test { get; set; }
}
Now, I am trying to instantiate derived class in Main():
static void Main(string[] args)
{
Derived obj = new Derived()
{
Licensed = () => { return true; },
Enabled = () => { return Licensed() && true; }, //access above delegate
};
}
The thing is in Enabled
implementation, I want to access Licensed delegate assigned just above. I am not able to achieve this as it is not allowed. Is this doable in some other way?
Upvotes: 2
Views: 385
Reputation: 64943
Note: I provide this answer to show some other approach to the OP to solve the problem. I won't try to say no, you can't with a full explanation since this has been already answered by @SergeyBerezovskiy.
Another option could be turning this into a fluent API.
When I need to set delegates I tend to think that they should be set once, never changed. Therefore, properties holding those delegates should be publicly readable and privately settable.
In the other hand, a fluently-configured object should be created using a factory method and its constructor will be private
.
Finally, each method on the fluent chain should also inject the instance being configured, while you'll end up setting a delegate which calls the one passed as argument to the configuration methods.
That is, you got what you want in a very elegant way.
public class Derived : Base
{
private Derived() {}
public static Derived Create() => new Derived();
public Func<bool> Licensed { get; private set; }
public Func<bool> Enabled { get; private set; }
public void LicensedIf(Func<Derived, bool> licensingCondition)
=> Licensed = () => licensingCondition(this);
public void EnabledIf(Func<Derived, bool> enablingCondition)
=> Enabled = () => enablingCondition(this);
}
// Fluent configuration of your *licensable object* gets self-documented
// by the usage!
// Oh, and see how EnableIf() takes advantage of C#6's null conditional
// operator to invoke the "Licensed" delegate if its really set. This is
// so safe!
var derived = Derived.Create().LicenseIf(d => true)
.EnableIf(d => d.Licensed?.Invoke() && true);
That thing of encapsulating a delegate inside delegate would be called currying in functional programming! See What is 'Currying'? if you're interested in this topic.
Upvotes: 2
Reputation: 236248
You cannot reference other properties in object initializer. C# Language Specification 7.6.10.2 Object initializers:
It is not possible for the object initializer to refer to the newly created object it is initializing.
But you can use old-fashioned property assignment:
var obj = new Derived { Licensed = () => true; };
obj.Enabled = () => obj.Licensed() && true;
Upvotes: 4