当前位置:健康减肥瘦身 > 美容护肤 > 悄悄的传说之

悄悄的传说之

文章作者:美容护肤 上传时间:2019-12-01

快乐的Lambda表达式

图片 1

  上一篇 私自的传说之 - 欢快的Lambda表明式(生龙活虎)笔者们安份守己的分析了须臾间Lambda表明式。知道了它和寄托以至平常方法的界别,而且通过测验对照他们中间的特性,然后大家经过IL代码深刻通晓了Lambda表明式,以致介绍了怎么在.NET中用拉姆da表达式来完结JavaScript中山高校行其道的局部方式。

  明天,大家跟着来看Lambda表明式在.NET中还会有啥特殊的耍法。

Lambda表达式玩转多态

  Lambda怎样完毕多态?大家用抽象类和虚方法了,为何还要用Lambda这家伙?且看下边包车型客车代码:

class MyBaseClass
{
    public Action SomeAction { get; protected set; }

    public MyBaseClass()
    {
        SomeAction = () =>
        {
            //Do something!
        };
    }
}

class MyInheritedClass : MyBaseClass
{
    public MyInheritedClass()
    {
        SomeAction = () => {
            //Do something different!
        };
    }
}

  大家的基类不是抽象类,也未尝虚方法,可是把品质通过信托的法门暴露出来,然后在子类中再一次为我们的SomeAction付与多个新的表达式。那就是我们兑现多态的历程,当然父类中的SomeAction的set有protected的保险等第,不然就能被外表随易改革了。然而那还不完善,父类的SomeAction在子类中被蒙蔽以往,大家到底访问不到它了,要清楚真实情状是我们能够透过base来访谈父类原来的办法的。接下来就是落实这几个了:

class MyBaseClass
{
    public Action SomeAction { get; private set; }

    Stack<Action> previousActions;

    protected void AddSomeAction(Action newMethod)
    {
        previousActions.Push(SomeAction);
        SomeAction = newMethod;
    }

    protected void RemoveSomeAction()
    {
        if(previousActions.Count == 0)
            return;

        SomeAction = previousActions.Pop();
    }

    public MyBaseClass()
    {
        previousActions = new Stack<Action>();

        SomeAction = () => {
            //Do something!
        };
    }
}

  下面包车型客车代码中,大家经过AddSomeAction来完结覆盖的同不平日间,将原来的不二等秘书籍保存在previousActions中。这样大家就足以保险双方同时存在了。

  大家精通子类是不可能掩盖父类的静态方法的,可是若是大家想实现静态方法的覆盖呢?

void Main()
{
    var mother = HotDaughter.Activator().Message;
    //mother = "I am the mother"
    var create = new HotDaughter();
    var daughter = HotDaughter.Activator().Message;
    //daughter = "I am the daughter"
}

class CoolMother
{
    public static Func<CoolMother> Activator { get; protected set; }

    //We are only doing this to avoid NULL references!
    static CoolMother()
    {
        Activator = () => new CoolMother();
    }

    public CoolMother()
    {
        //Message of every mother
        Message = "I am the mother";
    }

    public string Message { get; protected set; }
}

class HotDaughter : CoolMother
{
    public HotDaughter()
    {
        //Once this constructor has been "touched" we set the Activator ...
        Activator = () => new HotDaughter();
        //Message of every daughter
        Message = "I am the daughter";
    }
}

  这里如故选用了将拉姆da表明式作为品质,可以随即再一次赋值的特点。当然那只是二个简便的示范,真实项目中并不提议大家如此去做。 

措施字典

  实际上这几个形式大家在上大器晚成篇的回来方法中早就讲到了,只是未有这么二个名字而已,尽管是三个总计吧。好玩的事是那般的,你是或不是不常会写到switch-case语句的时候以为相当不足温婉?然而你又不想去整个什么工厂形式或许政策格局,那如何让你的代码看起来高级一点啊?

public Action GetFinalizer(string input)
{
    switch
    {
        case "random":
            return () => { /* ... */ };
        case "dynamic":
            return () => { /* ... */ };
        default:
            return () => { /* ... */ };
    }
}

//-------------------变身之后-----------------------
Dictionary<string, Action> finalizers;

public void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    finalizers.Add("random", () => { /* ... */ });
    finalizers.Add("dynamic", () => { /* ... */ });
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  好像看起来是不一样等了,有那么一些深意。可是风流倜傥想是颇有的秘籍都要放手那么些BuildFinalizers里面,这种组织格局其实是麻烦承当,大家来学习插件开垦的措施,让它本身去找所有大家须要的艺术。

static Dictionary<string, Action> finalizers;

// 在静态的构造函数用调用这个方法
public static void BuildFinalizers()
{
    finalizers = new Dictionary<string, Action>();

    // 获得当前运行程序集下所有的类型
    var types = Assembly.GetExecutingAssembly().GetTypes();

    foreach(var type in types)
    {
        // 检查类型,我们可以提前定义接口或抽象类
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            // 获得默认无参构造函数
            var m = type.GetConstructor(Type.EmptyTypes);

            // 调用这个默认的无参构造函数
            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

public Action GetFinalizer(string input)
{
    if(finalizers.ContainsKey(input))
        return finalizers[input];

    return () => { /* ... */ };
}

  如若要贯彻插件化的话,大家不仅仅要能够加载本程序集下的点子,还要能天天以至运营时去加载外界的主意,请继续往下看:

internal static void BuildInitialFinalizers()
{
    finalizers = new Dictionary<string, Action>();
    LoadPlugin(Assembly.GetExecutingAssembly());
}

public static void LoadPlugin(Assembly assembly)
{
    var types = assembly.GetTypes();
    foreach(var type in types)
    {
        if(type.IsSubclassOf(typeof(MyMotherClass)))
        {
            var m = type.GetConstructor(Type.EmptyTypes);

            if(m != null)
            {
                var instance = m.Invoke(null) as MyMotherClass;
                var name = type.Name.Remove("Mother");
                var method = instance.MyMethod;
                finalizers.Add(name, method);
            }
        }
    }
} 

  今后,大家就能够用这些措施,给它钦命程序集去加载大家须要的事物了。

  最后留下我们三个主题素材,大家能写递归说明式么?下边包车型地铁点子假诺用表明式如何写啊?

int factorial(int n)
{
    if(n == 0)
        return 1;
    else
        return n * factorial(n - 1);
}

  

本文由健康减肥瘦身发布于美容护肤,转载请注明出处:悄悄的传说之

关键词: