我可以在同一个类的另一个委托中访问委托吗?

时间:2017-03-07 13:58:11

标签: c# .net c#-4.0 c#-3.0

我不知道我的理解是否错误,但我想尝试做下面的事情:

我有一个有两个代表的基类:

 public class Base
 {
     public Func<bool> Licensed { get; set; }
     public Func<bool> Enabled { get; set; }
 }    

派生类如下所示:

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实施,我想访问上面指定的许可代理。因为不允许,我无法实现这一目标。这可以用其他方式吗?

2 个答案:

答案 0 :(得分:4)

您无法在对象初始值设定项中引用其他属性。 C#语言规范7.6.10.2对象初始化器:

  

对象初始化程序无法引用新的   创建的对象正在初始化。

但你可以使用老式的财产分配:

from random import random
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib import cm

n=11
tab = np.array([[random() for i in range(n)] for j in range(n)])
tab[1,2] = 2.
tab[3,4] = 2.
tab[5,6] = 3.
tab[7,8] = 3.

values1 = np.ma.masked_array(tab, tab > 1.)
values2 = np.ma.masked_array(tab, tab != 2.)
values3 = np.ma.masked_array(tab, tab != 3.)

# 50 values for later use from 0 to 1
greens = cm.Greens(np.linspace(0,1, num=50))
# 25 values for later use from 1 to 1.5
greensfill = cm.Greens(np.ones(25))
# 50 values red for later use from 1.5 to 2.5 
red = [(1,0,0,1)]*len(greens)
# 50 values gray for later use from 2.5 to 3.5 
gray = [(.5,.5,.5,1)]*len(greens)

colors = np.vstack((greens, greensfill, red, gray))
# in total we now have 175 colors in the colormap
mycmap = mcolors.LinearSegmentedColormap.from_list('my_colormap', colors)

#we now map those 175 colors to the range between 0 and 3.5
im = plt.imshow(tab, cmap = mycmap, interpolation="none", vmin=0, vmax=3.5)
cb = plt.colorbar(im)
cb.set_ticks([0,1,2,3])

plt.show()

答案 1 :(得分:2)

注意:我提供此答案以显示OP的其他方法来解决问题。我不会试图说不,你不能有完整的解释,因为@SergeyBerezovskiy已经回答了这个问题。

另一种选择可能是将其转换为流畅的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'?