• 从C# 2.0 爬向 C# 4.0—— 先说说 泛型——C# 是个优雅的语言


    前言

       开始时学的是C#2.0而且没有学完全。工作后,不是在忙着赶项目,就是对各种技术尝尝鲜,而语言的学习却没有什么进步。直到半年前开始入门Python(纯粹爱好,断断续续的学着)才发现——原来编程还可以这样!原来代码还可以这样写!

       沉溺于各种设计模式、框架、新鲜技术

       回眸一望

       忽然发现

       她

       依然如此优雅

       甚至

       更胜从前!

    目标

      补完C# 2.0 3.0的新特性,然后在研究研究4.0。本章先从泛型开始温习一下。

    参考链接

      详细读完这些文章,你就不用看我写的了!如有不明请往下,还是不明请留言,大家相互讨论。

    C#泛型简介

    Predicate泛型委托

    Func(T,TResut)委托

    泛型委托(C#编程指南)

    走进Linq-Linq大观园

    C++ 模板和 C# 泛型间的区别

    泛型

       有句经典的等式: 算法+ 数据结构   =   程序!写程序总会遇到一些算法相同(处理方法相似),但数据结构不同的情况。难道就为了把int 改成 double 、Struct或Class A ,而把代码再打一遍吗?

      你很勤快,不在乎多敲一次代码?不,程序员应该很懒!让机器帮我们去做吧,于是我们有了泛型——Class Stack<T>。

    C#2.0 引入了泛型它类似于C++的模板(都是C 一家亲嘛,另外推荐一篇利用C++模板来打印质数的博文,它的厉害之处在于利用c++模板的特性,在编译时计算出质数而不是运行时 ——质数打印),但是在实现和功能方面还是存在差异的。我们可以这样定义泛型

    1 /// <summary>
    2 /// 在类上定义
    3 /// </summary>
    4 /// <typeparam name="T"></typeparam>
    5   public class Stack<T>
    6 {
    7 public void Push(T value)
    8 { }
    9 }
    10
    11 /// <summary>
    12 /// 在方法里
    13 /// </summary>
    14   public class Stack
    15 {
    16 public void Push<T>(T value)
    17 { }
    18 public T Pop<T>(T value1, T value2) { return value1; }
    19 }
    20 /// <summary>
    21 /// 错误案例,因为 占位符 还没声明,就使用了。
    22 /// </summary>
    23   //public class StackT
    24 //{
    25 // public void Push(T value)
    26 // { }
    27 //}
    28
    29 //委托
    30   public delegate TResult Add<T,TResult>(T value);

      其实T 就是一个占位符(为啥是T?当然你也可以是V、R、Y,这得从它哥哥说起),个人认为把泛型里的T理解为占位符是最直接的。先声明<T> ,然后就可以在该泛型里,直接使用这个占位符T了。编译器会根据 调用泛型时指定的占位符T的类型,来替换 或推断出对应的类型。

    //声明
    public class Stack<T>
    {
    //在 Stack 的范围里 可以调用。
    public void Push(T value)
    { }

    public void Pop<V>(statck<V> s, params V[] p){}
    }

    在使用 class Stack  时 必须指定T  占位符是什么,编译器就能推断出 Push(T)的类型了。而Pop 里的V是另一个占位符,在使用时需要指定。

    Stack<int> stack = new Stack<int>();
    stack.Pop
    <string>("nihao ", "sdfsdf", "sdfsdf", "sdfsdfvwevwwve");

    其实这个例子除了表明一些语法外,没什么意义。

    泛型委托

       委托也可以定义泛型,将参数一般化。在.net 3.5 里为我们定义了几个常见的泛型委托Predicate<> Func<>  Action<> 等几个泛型。 有了这几个常用的委托我们写起代码来就更加方便了。

    View Code
    class Program
    {
    static void Main(string[] args)
    {

    Func
    <string, string> test1 = IsTooLong;
    Func
    <string, string> test2 = delegate(string str)
    {
    if (str.Length > 10)
    {
    return "Too long";
    }
    else
    {
    return "ok";
    }
    };
    Func
    <string, string> test3 = (str) => str.Length > 10 ? "Too long" : "ok";


    Console.WriteLine(test3(
    "sodiinbgweoeinbowevw"));




    Console.Read();
    }

    static string IsTooLong(String value)
    {
    if (value.Length > 10)
    {
    return "Too long";
    }
    else
    {
    return "ok";
    }
    }


    }

    代码使用 Func<> 定义了3个有返回值的委托, 然后再将委托的运行结果输出,如果字符串的长度大于10 则输出“Too Long”。

    test1里 也可以写成“test1 = new Func<string, string>(IsTooLong);” ,但是直接赋予 =IsTooLong更简洁不是吗? 这得归功于编译器的委托推理,它能够推断出我们分配到委托的类型,并验证该方法是否与签名相匹配。

    test2 用到了 匿名方法

    test3 则是使用了lambda 表达式,这个是不是更简洁。

    后记

      这里只简单的介绍一下泛型,详细的信息可以查看参考链接。把T 理解为占位符 就好,编译器会帮我们替换它的。

  • 相关阅读:
    python第四十二天 socket ---ssh
    python第四十一天---作业:简单FTP
    python第三十七天--异常--socket
    python第三十六天-----类中的特殊成员方法
    python第三十五天-----作业完成--学校选课系统
    python第三十三天----静态方法、类方法、属性方法
    RESTful Web Services初探
    OLAT & OLTP
    Solr4.8.0源码分析(7)之Solr SPI
    Solr4.8.0源码分析(6)之非排序查询
  • 原文地址:https://www.cnblogs.com/keyindex/p/1971728.html
Copyright © 2020-2023  润新知