C# 框架入口功能的实现

目录

一、概述

二、Lambad 和 委托

三、Optional 关键字

四、实现效果

结束


一、概述

在我们工作中,为了开发效率,避免不了需要使用一些框架,大部分框架初始化时,必须要向框架入口传入一些参数,以实现不同的功能,那么问题来了,框架入口的写法是如何实现的呢?

我们就以 NanUI 这个框架作为例子,看看这个框架的启动入口,看起来就非常的优雅好看吧,其实实现这个效果也不难,而且没有那么多高级语法,那么这次就以 NanUI 框架这个启动入口来写一个类似的 Demo 出来,学习这些知识之前,你必须了解 C# 的委托,Lambda 表达式的一些基础知识,后面我也会做一些相关的介绍。

NanUI 的框架入口:

using NetDimension.NanUI;
using NetDimension.NanUI.EmbeddedFileResource;
using NetDimension.NanUI.LocalFileResource;
using NetDimension.NanUI.ZippedResource;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
using Xilium.CefGlue;
 
namespace NanUIFramework
{
    static class Program
    {

        /// <summary>
        /// 应用程序的主入口点。
        /// </summary>
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
 
 
            WinFormium.CreateRuntimeBuilder(env =>
            {
                env.CustomCefSettings(settings =>
                {
                    // 在此处设置 CEF 的相关参数                
                });
                env.CustomCefCommandLineArguments(commandLine =>
                {
                    // 在此处指定 CEF 命令行参数
                    commandLine.AppendSwitch("disable-pinch");
                });
            }, app =>
            {
                //如果您希望只运行一个实例,请使用此设置
                app.UseSingleInstance(() =>
                {
                    MessageBox.Show("实例已经运行,只能运行一个实例", "Single Instance", MessageBoxButtons.OK, MessageBoxIcon.Warning);
                });
 
                //清除所有缓存文件,如cookie,历史,本地存储等。
                app.ClearCacheFile();
 
                //嵌入式资源
                app.UseEmbeddedFileResource("http", "Load.Resource.Html", "View");
 
                //读取本地资源  注册LocalFileResource处理程序,它可以处理本地文件夹中的文件资源。
                //app.UseLocalFileResource("http", "Load.Local.Html", System.IO.Path.Combine(Application.StartupPath, "View"));
 
                //读取ZIP资源
                //app.UseZippedResource("http", "archive.app.local", Application.StartupPath + "\\View\\index.zip");
 
                //实例化界面
                MainIndex MainIndexs = new MainIndex();
 
                // 指定启动窗体
                app.UseMainWindow(context => MainIndexs);
            })
            .Build()
            .Run();
        }
    }
}

二、Lambad 和 委托

"Lambda表达式"是一个匿名函数,是一种高效的类似于函数式编程的表达式,Lambda简化了开发中需要编写的代码量。它可以包含表达式和语句,并且可用于创建委托或表达式目录树类型,支持带有可绑定到委托或表达式树的输入参数的内联表达式。

比如有这样一个场景,在给出的List集合中找出数字大于等于18的数字,假如我们不知道有 Linq 这种东西!

详细的介绍可以参考我的帖子:

C# Lambda表达式和委托_熊思宇的博客-CSDN博客

下面看看这段代码:

using System;

namespace 委托的用法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test((user) =>
            {
                user.Age = 23;
                user.Height = 167;
                user.Name = "老王";
            });

            Console.ReadKey();
        }

        static void Test(Action<UserInfo> action)
        {
            UserInfo userInfo = new UserInfo();
            action?.Invoke(userInfo);
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }
        
        public int Age { get; set; }

        public int Height { get; set; }
    }
}

执行 Test 方法时,这么写是什么意思,换一种写法,那么它就是这样:

using System;

namespace 委托的用法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Action<UserInfo> action = (UserInfo user) =>
            {
                user.Age = 23;
                user.Height = 167;
                user.Name = "老王";
            };
            Test(action);

            Console.ReadKey();
        }

        static void Test(Action<UserInfo> action)
        {
            UserInfo userInfo = new UserInfo();
            action?.Invoke(userInfo);
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }
        
        public int Age { get; set; }

        public int Height { get; set; }
    }
}

这样是否明白多了,更简单一些它就是这样

using System;

namespace 委托的用法
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Test(GetUser);
            Console.ReadKey();
        }

        static void GetUser(UserInfo user)
        {
            user.Age = 23;
            user.Height = 167;
            user.Name = "老王";
        }

        static void Test(Action<UserInfo> action)
        {
            UserInfo userInfo = new UserInfo();
            action?.Invoke(userInfo);
        }
    }

    public class UserInfo
    {
        public string Name { get; set; }

        public int Age { get; set; }

        public int Height { get; set; }
    }
}

Invoke 的用法在微软官方的有介绍,调用 Invoke 后,相当于 把 userInfo 这个实例化的对象,作为参数传到了 GetUser 方法中,由  GetUser 方法进行了赋值,然后 userInfo 就有了实际的值。

UserInfo userInfo = new UserInfo();
action?.Invoke(userInfo);

如下图

三、Optional 关键字

C# 常用的关键字微软文档:

C# 关键字 | Microsoft Learn

在这里我看了一下,根本找不到 Optional 这个关键字,在微软的文档中搜索,也只是找到 VB 的资料

在 VB 文档中,就是可选参数的意思,其实用法挺简单

在 C# 中,我们调用方法,必须给方法的每一个参数传值,如下

using System;

namespace 可选参数
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int result = Add(1, 3, 4);
            Console.WriteLine("结果:{0}",result);
            Console.ReadKey();
        }

        static int Add(int num1, int num2, int num3)
        {
            return num1 + num2 + num3;
        }
    }
}

Optional 关键字的作用:

using System;
using System.Runtime.InteropServices;

namespace 可选参数
{
    internal class Program
    {
        static void Main(string[] args)
        {
            int result = Add(1, 3);
            Console.WriteLine("结果:{0}",result);
            Console.ReadKey();
        }

        static int Add([Optional] int num1, int num2, [Optional] int num3)
        {
            return num1 + num2 + num3;
        }
    }
}

运行:

[Optional] 关键字放参数所放的位置不明确,会报错

四、实现效果

根据上面的理论,我们新建一个 C# 控制台项目,代码如下

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Runtime.InteropServices;

namespace Test4
{
    internal class Program
    {
        static void Main(string[] args)
        {
            Framework.Set(config =>
            {
                config.SetAge(5);
                config.SetName("张三");
                config.SetOther(mode =>
                {
                    mode.Address = "广东省,深圳市";
                    mode.Height = 180;
                    mode.Color = "Black";
                });
            }, setting =>
            {
                setting.SetIP("127.0.0.1");
                setting.SetDownloadURL("www.sfdf.com");
            }).Start();

            Console.ReadKey();
        }
    }

    //框架
    public class Framework
    {
        internal static Configuration Configurations { get; set; } = new Configuration();

        internal static Setting Settings { get; set; } = new Setting();

        public static Project Set([Optional] Action<Configuration> config, [Optional] Action<Setting> setting)
        {
            config.Invoke(Configurations);
            setting.Invoke(Settings);

            return new Project();
        }
    }

    //项目
    public class Project
    {
        public void Start()
        {
            Console.WriteLine("启动项目");
        }
    }

    //配置
    public class Configuration
    {   

        public void SetAge(int age)
        {
            Console.WriteLine("设置年龄:" + age);
        }

        public void SetName(string name)
        {
            Console.WriteLine("设置名字:" + name);
        }

        public void SetOther(Action<Mode> mode)
        {
            Mode data = new Mode();
            mode.Invoke(data);
            Console.WriteLine("设置其他");
            Console.WriteLine("Height:" + data.Height);
            Console.WriteLine("Color:" + data.Color);
            Console.WriteLine("Address:" + data.Address);
        }
    }

    //设置
    public class Setting
    {
        public void SetIP(string ip)
        {
            Console.WriteLine("设置IP:" + ip);
        }

        public void SetDownloadURL(string ip)
        {
            Console.WriteLine("下载地址:" + ip);
        }
    }

    public class Mode
    {
        public int Height { get; set; }
        public string Color { get; set; }
        public string Address { get; set; }
    }
}

运行:

结束

如果这个帖子对你有所帮助,欢迎 关注 + 点赞 + 留言

end

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

熊思宇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值