zoukankan      html  css  js  c++  java
  • C#函数式程序设计之泛型

     

    Intellij修改archetype Plugin配置

    2014-03-16 09:26 by 破狼, 204 阅读, 0 评论, 收藏编辑

    Maven archetype plugin为我们提供了方便的创建 project功能,Archtype指我们项目的骨架,作为项目的脚手架。 如fornt end的yo之类。我们能够通过简单的一行控制台command line创建你所需要的项目结构:

    1
    2
    3
    4
    5
    6
    mvn archetype:generate
      -DarchetypeGroupId=<archetype-groupId>
      -DarchetypeArtifactId=<archetype-artifactId>
      -DarchetypeVersion=<archetype-version>
      -DgroupId=<my.groupid>
      -DartifactId=<my-artifactId>

    常用的Maven archetype plugin有:

    • org.apache.maven.archetypes:maven-archetype-quickstart
    • org.apache.maven.archetypes:maven-archetype-site
    • org.apache.maven.archetypes:maven-archetype-webapp
    • 以及spring或者第三方提供了一些archetype plugin。

    同时在java世界强大的IDE Intellij也支持按照maven archetype 创建java项目。你只需要选择maven 创建项目,在最后选择你希望的 archetype plugin,然后就可以喝杯coffe等待build success。

    关于如何自定义项目的Maven archetype plugin,博主将会 在后续的文章介绍。在此次博文将是记录如果去掉你手动在intellij中添加 的archetype plugin。

    mac版本,你可以找到文件:

    ~/Library/Caches/IntelliJIdea<version>/Maven/Indices/UserArchetypes.xml

    然后用你喜欢的编辑器打开它(例如博主当前使用的Atom):

    <?xml version="1.0" encoding="UTF-8"?>
    <archetypes>
            <archetype groupId="com.github.greengerong" artifactId="components-archetype" version="1.0.0" />
    </archetypes>    

    你可以在xml的archetypes节点增加或者删除修改配置,然后重新启动你的Intellij。

    本博客已经转移个人博客破狼,也有有部分更新,但不保证及时维护,如果你希望及时看到本人的新日志,那请订阅破狼-RSS
    ThoughtWorks 正在火热招聘中,有兴趣者,请点击ThoughtWorks招聘


    作者:破  狼 
    出处:http://www.cnblogs.com/whitewolf/ 

    C#函数式程序设计之泛型(上)

     

    在面向对象语言中,我们可以编写一个元素为某个专用类型(可能需要为此创建一个ListElement)的List类,或者使用一个非常通用、允许添加任何类型元素的基类(在.NET中,首先想到的是System.Object)。这两种方法都有缺点。使用通用类型的基类时,很可能会把不相容的元素添加到列表中;如果使用元素为专用类型的列表,只是推迟此问题的发生,因为实际类型是在最后封装到这个类中。泛型提供了这个问题的解决方法。

    一般而言,一个泛型类型G可以应用于一个或多个其他类型——如O1、O2等——其思想是,G的实现不需要对Ox等类型知道很多。

    C#函数式程序设计之泛型函数

    任何方法在为方法签名添加一个或多个类型参数后,就成为泛型。如下所示:

    1
    2
    3
    4
    static void OutputThing<T>(T thing)
    {
          Console.WriteLine("Thing: {0}",thing);
    }   

    这里T是类型变量,它出现在方法名后面的一对尖括号中。这样声明后,这个参数就可以在参数列表中和方法体重当成类型使用。这个方法并不关心这个thing元素和它的类型,它只是把它的值传递给其他方法以进一步处理。

    下面是用显示类型参数调用这个函数:

    1
    2
    OutputThing<string>("A string");
    OutputThing<int>(42);

    使用显式类型参数意味着这个类型要受到Visual Studio的智能感知和C#编译器的双重检查。如下面这个调用会产生编译错误信息:

    1
    OutputThing<double>("A string");

    错误如下:

    尽管这个例子很简单,但它说明泛型的一个作用:不是使用类型对象的参数,而是在调用中显式说明类型,这回启动严格的类型检查。

    另一方面,许多程序员认为直接使用显式类型过于草率,OutputThing方法也可以像下面这样调用:

    1
    2
    OutputThing("A string");
    OutputThing(42);

    这里使用类型推断机制可以根据字面值推断它的类型。这并不是一个无类型调用,在OutputThing方法中还有一个类型变量T。上面两个调用语句实际上T分别代表了string和int,编译器会在编译时自动为它们替换为该类型。

    然而,许多程序员把C#类型推断看成是一个只有在必要时才使用的功能,而不是一个任何时候都可以使用的通用工具,这是正确的,使用类型推断,会让复杂的代码的可读性变差。

    下面是一个稍微复杂(同时也比较有用)的有关泛型的李子

    1
    2
    3
    4
    5
    6
    7
    static void Apply<T>(IEnumerable<T> sequence, Action<T> action)
    {
        foreach (T item in sequence)
        {
            action(item);
        }
    }

    本例中也有一个类型参数T,但是它作用在这个方法的两个参数上,它们之间存在一种关联:第一个参数是事件序列,第二个参数是一个委托,此委托作用的参数就是在此序列中的事件类型。这正是泛型表现出强大功能的地方,如果不使用泛型,但仍然希望此方法可以灵活应用于不同类型,就无法表现出这种关联性。

    泛型元素并不关心类型本身。下面是对Apply方法的调用:

    1
    2
    var values = new List<int> { 10, 20, 35 };
    Apply(values, v => Console.WriteLine("Value:{0}", v));

    调用Apply方法,但是省略了泛型参数,编译器需要推断Apply调用语句中参数T的类型,为此需要检查参数。

    C#函数式程序设计之泛型类

    也可以给类添加类型信息。在这种情况下,类型参数的作用域是整个类,但其用法与前面完全一样:它代表某个类型。下面的例子是一个链表的实现(不完整):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class ListItem<T>
    {
        public ListItem(T value)
        {
            this.value = value;
        }
     
        private ListItem(T value, ListItem<T> next)
            : this(value)
        {
            this.next = next;
        }
     
        private readonly T value;
        public T Value
        {
            get { return value; }
        }
     
        private ListItem<T> next;
        public ListItem<T> Prepend(T value)
        {
            return new ListItem<T>(value, this);
        }
    }

    ListItem类有一个泛型参数T,这个参数封装在ListItem容器中,在类中任何需要显式类型的位置都可以使用这个类。使用泛型会使ListItem类更加灵活,因为它可以把任何其他类型的信息封装到链表列中。

    同时,泛型系统会使编译器的类型检查功能更强大。上例中的Prepend方法只接受T类型的值。从ListItem类的实例角度来看,T是固定的,换言之,新的值必须与当前实例的值具有相同类型。分析下面的例子:

    1
    2
    3
    4
    5
    6
    public static void List()
    {
        var intItem = new ListItem<int>(10);
        var secondItem = intItem.Prepend(20);
        var thirdItem = secondItem.Prepend("string");
    }   

    这里,当ListItem类与new关键字一起使用时,要在类名中添加一个类型参数,现在保存在ListItem变量中的实例是类型化的,包含了类型为int的值。其结果是,Prepend方法可以接受一个为int的类型参数,因此,上例会报错:

    泛型语法的最后一个部分是多个类型参数。在任何情况下,只要使用类型参数,就不会只有一个。看下面的代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    public class Test<T1, T2>
    {
        private Test(T1 val1, T2 val2)
        {
            this.val1 = val1;
            this.val2 = val2;
        }
        private readonly T1 val1;
        public T1 Val1
        {
            get
            {
                return val1;
            }
        }
     
        private readonly T2 val2;
        public T2 Val2
        {
            get
            {
                return val2;
            }
        }
    }

    使用多个泛型参数实际上并没有什么特别之处。重要的是必须认识到这是完全可行的,最后一点是:类中的类型参数与方法中的类型参数可以同时使用,但是必须保证它们不会发生冲突。

     
     
    分类: C#专题
  • 相关阅读:
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    Security and Cryptography in Python
    基于分布式锁解决定时任务重复问题
    基于Redis的Setnx实现分布式锁
    基于数据库悲观锁的分布式锁
    使用锁解决电商中的超卖
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/3604147.html
Copyright © 2011-2022 走看看