我可以在同一 class 的另一个委托中访问委托吗?
Can I access delegate inside another delegate of same class?
我不知道我的理解是否错误,但我正在尝试执行以下操作:
我有一个基地 class 有两个代表:
public class Base
{
public Func<bool> Licensed { get; set; }
public Func<bool> Enabled { get; set; }
}
和派生的class如下图:
public class Derived : Base
{
public int Test { get; set; }
}
现在,我正在尝试在 Main():
中实例化派生的 class
static void Main(string[] args)
{
Derived obj = new Derived()
{
Licensed = () => { return true; },
Enabled = () => { return Licensed() && true; }, //access above delegate
};
}
事情在 Enabled
实现中,我想访问上面分配的许可委托。我无法实现这一目标,因为这是不允许的。这可以通过其他方式实现吗?
您不能在对象初始值设定项中引用其他属性。 C# 语言规范 7.6.10.2 对象初始值设定项:
It is not possible for the object initializer to refer to the newly
created object it is initializing.
但是你可以使用老式的属性赋值:
var obj = new Derived { Licensed = () => true; };
obj.Enabled = () => obj.Licensed() && true;
注意:我提供这个答案是为了向 OP 展示解决问题的其他方法。我不会说 不,你不能 给出完整的解释,因为 .
已经回答了这个问题
另一种选择可能是将其变成 流利的 API。
当我需要设置代表时,我倾向于认为它们应该设置一次,永远不会改变。因此,持有这些委托的属性应该是公开可读和私有设置的。
另一方面,应使用 工厂方法 创建流畅配置的对象,其构造函数将为 private
.
最后,fluent 链上的每个方法还应该注入正在配置的实例,而您最终将设置一个委托,该委托调用作为参数传递给配置方法的委托。
也就是说,你以一种非常优雅的方式得到了你想要的东西。
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);
将委托封装在委托中的事情在函数式编程中称为currying!如果您对此主题感兴趣,请参阅 What is 'Currying'?。
我不知道我的理解是否错误,但我正在尝试执行以下操作:
我有一个基地 class 有两个代表:
public class Base
{
public Func<bool> Licensed { get; set; }
public Func<bool> Enabled { get; set; }
}
和派生的class如下图:
public class Derived : Base
{
public int Test { get; set; }
}
现在,我正在尝试在 Main():
static void Main(string[] args)
{
Derived obj = new Derived()
{
Licensed = () => { return true; },
Enabled = () => { return Licensed() && true; }, //access above delegate
};
}
事情在 Enabled
实现中,我想访问上面分配的许可委托。我无法实现这一目标,因为这是不允许的。这可以通过其他方式实现吗?
您不能在对象初始值设定项中引用其他属性。 C# 语言规范 7.6.10.2 对象初始值设定项:
It is not possible for the object initializer to refer to the newly created object it is initializing.
但是你可以使用老式的属性赋值:
var obj = new Derived { Licensed = () => true; };
obj.Enabled = () => obj.Licensed() && true;
注意:我提供这个答案是为了向 OP 展示解决问题的其他方法。我不会说 不,你不能 给出完整的解释,因为
另一种选择可能是将其变成 流利的 API。
当我需要设置代表时,我倾向于认为它们应该设置一次,永远不会改变。因此,持有这些委托的属性应该是公开可读和私有设置的。
另一方面,应使用 工厂方法 创建流畅配置的对象,其构造函数将为 private
.
最后,fluent 链上的每个方法还应该注入正在配置的实例,而您最终将设置一个委托,该委托调用作为参数传递给配置方法的委托。
也就是说,你以一种非常优雅的方式得到了你想要的东西。
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);
将委托封装在委托中的事情在函数式编程中称为currying!如果您对此主题感兴趣,请参阅 What is 'Currying'?。