c#杂记

LINQ

  • linq分为方法语法和查询语法(和sql语句相似,微软推荐)

  • EF 查询的两种 写法。 linq 方法 或者 lambda方法,其中 ,只有tolist()的时候,才会真正的 在数据库中执行。如果没有 tolist 方法,那么province1是 iqueable类型

  • Linq简介


委托

  • 声明一个委托,其实就是个“命令”

  • Delegate至少0个参数,至多32个参数,可以无返回值,也可以指定返回值类型。这个是祖宗。

  • Func可以接受0个至16个传入参数,必须具有返回值。

  • Action可以接受0个至16个传入参数,无返回值。

  • Predicate只能接受一个传入参数,返回值为bool类型。

// 委托多播实例:例如小明叫小张买完车票,之后接着又让他带张电影票:
// 小张类
public class MrZhang
    {
    // 其实买车票的悲情人物是小张
    public static void BuyTicket()
    {
            Console.WriteLine("NND,每次都让我去买票,鸡人呀!");
    }

    public static void BuyMovieTicket()
    {
        Console.WriteLine("我去,自己泡妞,还要让我带电影票!");
    }
}

//小明类
class MrMing
{
    // 声明一个委托,其实就是个“命令”
    public delegate void BugTicketEventHandler();

    public static void Main(string[] args)
    {
        // 这里就是具体阐述这个命令是干什么的,本例是MrZhang.BuyTicket“小张买车票”
        BugTicketEventHandler myDelegate = new BugTicketEventHandler(MrZhang.BuyTicket);

        myDelegate += MrZhang.BuyMovieTicket;
        // 这时候委托被附上了具体的方法
        myDelegate();
        Console.ReadKey();
    }
}
  • 接口是为了实现共同的标准;抽象是为了代码的复用。当然,接口和抽象,都可以实现里氏替换。

  • 我们在设计架构的时候,使用的EF的时候往往会在参数调用的时候放一个Expression<Func<T, bool>>表示参数。

  • Func<TObject, bool> 是 一个参数为 TObject 类型的参数 返回值为bool 类型的匿名函数

  • Func<TObject, bool>是委托(delegate), Expression<Func<TObject, bool>>是表达式, Expression编译后就会变成delegate,才能运行。

// Func<TObject, bool> 是 一个参数为 TObject 类型的参数 返回值为bool 类型的匿名函数
Func<string, bool> func = delegate(string s) {
    return true;
};

拓展方法

参数中带this的原因
public static class StringExtension
{
    public static void Foo(this string s)
    {
        Console.WriteLine("Foo invoked for {0}", s);
    }
}
  • 为什么这里会有一个this关键字,做什么用?其实这就是扩展方法!这个扩展方法在静态类中声明,定义一个静态方法,其中第一个参数定义可它的扩展类型。Foo()方法扩展了String类,因为它的第一个参数定义了String类型,为了区分扩展方法和一般的静态方法,扩展方法还需要给第一个参数使用this关键字。

  • 现在就可以使用带string类型的Foo方法了:

  • string s="Hello"; s.Foo();

  • 结果在控制台上显示Foo invoked for Hello ,因为Hello是传送给Foo方法的字符串。

  • 归纳:扩展方法可以写入最初没有提供该方法的类中。还可以把方法添加到实现某个接口的任何类中,这样多个类可以使用相同的实现代码。

  • 例子:

// 有没有想过要检查一个字符串变量是否是个合法的电子邮件地址? 在今天,你大概需要通过调用一个单独的类(或许通过一个静态方法)来实现检查该字符串变量是否合法。譬如,象这样:
string email = Request.QueryString["email"];
    if ( EmailValidator.IsValid(email) ) {
}
// 而使用C#中的新“扩展方法”语言特性的话,我则可以添加一个有用的“IsValidEmailAddress()”方法到string类本身中去,该方法返回当前字符串实例是否是个合法的字符串。然后我可以把我的代码重写一下,使之更加干净,而且更具描述性,象这样:
string email = Request.QueryString["email"];
    if ( email.IsValidEmailAddress() ) {
}

多线程 异步编程

[Route("api/[controller]")]
    public class ValuesController : Controller
    {
        // GET: api/<controller>
        [HttpGet("get")]
        public async Task<string> Get()
        {
            var info = string.Format("api执行线程:{0}", Thread.CurrentThread.ManagedThreadId);
            var infoTask = await TaskCaller();//使用await

            var infoTaskFinished = string.Format("api执行线程(task调用完成后):{0}", Thread.CurrentThread.ManagedThreadId);
            return string.Format("{0},{1},{2}", info, infoTask, infoTaskFinished);
        }

        private async Task<string> TaskCaller()
        {
            await Task.Delay(5000);
            return string.Format("task 执行线程:{0}", Thread.CurrentThread.ManagedThreadId);
        }
    }
/*
 * 结果为 [ api执行线程9,task执行线程:10,api执行线程(task调用完成后):9 ]
 * 一开始运行在线程10,后来跳到async方法中执行在线程8中,在没有使用await时,主线程并没有停下来,还是按照自己的路往下走,
 * 直到async使用了await方法,下面的代码也是交给了子线程。
 */
posted @ 2020-04-08 14:55  牛魔王呀  阅读(206)  评论(0编辑  收藏  举报