C# 编程技巧

前往我的主页以获得更好的阅读体验C# 编程技巧 - DearXuan的主页icon-default.png?t=M3C8https://blog.dearxuan.com/2021/11/01/C-%E7%BC%96%E7%A8%8B%E6%8A%80%E5%B7%A7/

可空类型

概念

在一个类型后面加上问号"?"表示可空类型

例如 int? a 表示a可以是一个数字,也可以是null

转换

对于非空的情况,可以添加显式转换

int? a = 10;
int b = (int)a;
Console.WriteLine(b);

但是当a为null时会报错,因此需要加上if语句

int? a = null;
int b = 
    a == null 
    ? -1 
    : (int)a;
Console.WriteLine(b);
//输出: -1

扩展方法

概念

扩展方法被定义在非泛型静态类中,扩展方法能够为现有的类添加新的方法,而无需定义新的类

示例

幂运算需要用到Math.Pow()函数,通过扩展方法,可以在int类型中添加Pow()方法,更快捷地计算幂

class Program
{
    static void Main(string[] args)
    {
        int a = 2;
        //计算2的10次方
        Console.WriteLine(a.Pow(10));
        Console.ReadKey();
    }
}

public static class Extend
{
    public static int Pow(this int num, int value)
    {
        return (int)Math.Pow(num, value);
    }
}

序列化对象的二进制储存

通过将一个类序列化,可以用二进制的方式在硬盘上保存这个类

[Serializable]
class Struct
{
    public int a = 10;
    public string b = "123";
    public Object c;
}

如果对象中出现对其它对象的引用,那么被引用的对象也会被写入硬盘里,在下次读取时仍然可用

static void Main(string[] args)
{
    Struct s = new Struct()
    {
        a = 99,
        b = "DearXuan",
        c = new Struct()
    };
    //保存
    using(FileStream fileStream1 = new FileStream(@"D:\1.xuan",FileMode.OpenOrCreate))
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        binaryFormatter.Serialize(fileStream1, s);
    }
    //读取
    using (FileStream fileStream = new FileStream(@"D:\1.xuan", FileMode.OpenOrCreate))
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        Struct ss = binaryFormatter.Deserialize(fileStream) as Struct;
        Console.WriteLine(ss.a);
        Console.WriteLine(ss.b);
        Console.WriteLine(((Struct)ss.c).a);
    }
    Console.ReadLine();
}

由于数据是二进制的形式储存,因此文件后缀名可以任意取

UWP的UI线程

UI线程

UI线程维护一个消息队列,所有的UI事件都会被送入消息队列中,在UI线程里执行。如果UI线程中存在耗时操作,就会导致消息得不到及时处理,程序无法响应输入,出现界面卡死

异步任务

使用async修饰方法,使之成为异步任务,用await修饰语句,使之成为等待任务

await修饰的代码将会在子线程中执行,并且不会有返回值

下面的代码生成了一个弹窗,使用await修饰ShowAsync(),使之不会阻塞UI线程

public async static void ShowOKDialog(string title, string content, Action onOkClick, Action onCloseClick)
{
    ContentDialog dialog = new ContentDialog();
    dialog.Title = title;
    dialog.Content = content;
    dialog.PrimaryButtonText = "好的";
    dialog.CloseButtonText = "取消";
    dialog.DefaultButton = ContentDialogButton.Primary;
    if(onOkClick != null)
    {
        dialog.PrimaryButtonClick += (_s, _e) => { onOkClick(); };
    }
    if(onCloseClick != null)
    {
        dialog.CloseButtonClick += (_s, _e) => { onCloseClick(); };
    }
    await dialog.ShowAsync();
}

想要对用户的点击事件做出响应,只需要为“确定”和“取消”按钮添加点击事件即可

跨线程更新UI

使用以下代码将函数放在UI线程执行。如果涉及UI更新的函数在子线程中执行则会报错

public async static void Invoke(Action action, CoreDispatcherPriority Priority = CoreDispatcherPriority.Normal)
{
    await CoreApplication.MainView.CoreWindow.Dispatcher.RunAsync(Priority, () => { action(); });
}

默认参数

使用默认参数

直接在方法的参数里为变量赋值,其值会作为默认值传入

public static int add(int a = 5,int b = 10,int c = 15)
{
    return a + b + c;
}

此时调用add(),会返回30

static void Main(string[] args)
{
    Console.Write(add());
    //结果: 30
    Console.ReadLine();
}

覆盖默认参数

按顺序在add()中输入参数,默认参数将会被覆盖

static void Main(string[] args)
{
    Console.Write(add(0,0));
    //结果: 15
    Console.ReadLine();
}

public static int add(int a = 5,int b = 10,int c = 15)
{
    return a + b + c;
}

上面的代码在调用add()时输入了两个参数,但是add()有三个参数,因此前两个被覆盖了

如果希望不按顺序,只需要在参数前面加上变量名

static void Main(string[] args)
{
    Console.Write(add(a: 0, c: 0));
    //结果: 10
    Console.ReadLine();
}

public static int add(int a = 5,int b = 10,int c = 15)
{
    return a + b + c;
}

上面的代码指定了a和c的变量值为0,而b仍为默认值,因此输出结果10

自动释放资源

IDispose接口

在using语句中定义的对象,将会在脱离using语句后自动释放资源

IDispose接口提供了一种方法来让程序自动释放资源,你需要把释放资源的语句写在Dispose()函数中

class Program
{
    static void Main(string[] args)
    {
        using(Example example = new Example())
        {
            Console.WriteLine("1");
        }
        // 运行结果:
        // Create
        // 1
        // Dispose
    }
}

class Example: IDisposable
{
    public Example()
    {
        Console.WriteLine("Create");
    }

    public void Dispose()
    {
        Console.WriteLine("Dispose");
    }
}

在读取文件时,将FileStream定义在using语句中,可以在执行完毕后自动释放,以免长时间占用

using(FileStream fileStream = new FileStream(@"D:\1.xuan",FileMode.OpenOrCreate))
{
    //读取文件
}

析构函数

析构函数与构造函数相反,析构函数在对象被gc释放时调用,因此你无法控制它被调用的具体时间

析构函数中不应该出现任何耗时操作或死循环,否则函数将会被系统强行中断

class Program
{
    static void Main(string[] args)
    {
        Example example = new Example();
        example = null;
    }
    // 运行结果:
    // Create
    // Dispose
}

class Example
{
    public Example()
    {
        Console.WriteLine("Create");
    }

    ~Example()
    {
        Console.WriteLine("Dispose");
    }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
1 网上教学的发展趋势与现状 1 1.2 开发背景 2 1.3 网上答疑辅导系统开发的目的 2 1.4 网上答疑辅导系统开发的意义 2 1.5 本文研究的内容和目标 2 第2章 关键技术介绍 4 2.1 ASP.NET技术介绍 4 2.1.1 .NET简介 4 2.1.2 ASP.NET简介 4 2.2 SQL Server 2000 6 2.3 IIS 5.0 7 2.4 系统开发环境介绍 7 第3章 系统分析 8 3.1 可行性分析 8 3.1.1操作上的可行性 8 3.1.2技术上的可行性 8 3.1.3时机上的可行性 8 3.1.4管理上的可行性 8 3.2 需求分析 9 3.3 系统的业务流图 10 3.4 数据流程图 10 第4章 总体设计 14 4.1 系统设计 14 4.1.1 目标设计 14 4.1.2 设计思想 14 4.1.3 系统功能分析和设计 15 4.1.3.1 系统功能模块的详细介绍 15 4.1.3.2 系统的逻辑功能划分 16 4.2 数据库的实现 18 4.2.1 数据库的需求分析 18 4.2.2 数据库的概念结构设计 19 4.2.3 数据库的逻辑设计 21 4.2.4 数据库访问的设计 23 第5章 详细设计 25 5.1 主界面设计 25 5.1.1 母版页(MasterPage.aspx)的设计 25 5.1.2 主界面(main.aspx)的设计 25 5.2 登录界面的设计 26 5.3 在线答疑(聊天室)的设计 27 5.3.1 聊天登录 27 5.3.2 保存聊天信息 27 5.3.3 获取聊天信息 28 5.3.4 格式化显示聊天信息 29 5.3.5 设计聊天界面 29 5.3.6 实现聊天功能 29 5.4 留言答疑(留言板)的设计与实现 31 5.4.1 留言板页面设计 31 5.4.2 留言板功能的实现 33 5.5课件学习的设计与实现 34 5.6 上传下载模块的设计与实现 35 5.6.1 上传文件模块的设计与实现 35 5.6.2 下载文件模块的设计与实现 37 5.7公告信息的设计与实现 40 5.8系统后台管理的设计与实现 40 5.8.1 留言管理 41 5.8.2 课件管理 42 5.8.3 公告管理 42 5.8.4 用户管理 42

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Dear_Xuan

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

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

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

打赏作者

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

抵扣说明:

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

余额充值