第五章 泛型

DocumentManager

namespace Wrox.ProCSharp.Generics
{
  public interface IDocument
  {
    string Title { get; set; }
    string Content { get; set; }
  }

  public class Document : IDocument
  {
    public Document()
    {
    }

    public Document(string title, string content)
    {
      this.Title = title;
      this.Content = content;
    }

    public string Title { get; set; }
    public string Content { get; set; }
  }

}
View Code
using System;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Generics
{
  public class DocumentManager<TDocument>
      where TDocument : IDocument
  {
    private readonly Queue<TDocument> documentQueue = new Queue<TDocument>();

    public void AddDocument(TDocument doc)
    {
      lock (this)
      {
        documentQueue.Enqueue(doc);
      }
    }

    public bool IsDocumentAvailable
    {
      get { return documentQueue.Count > 0; }
    }

    public void DisplayAllDocuments()
    {
      foreach (TDocument doc in documentQueue)
      {
        Console.WriteLine(doc.Title);
      }
    }


    public TDocument GetDocument()
    {
      TDocument doc = default(TDocument);
      lock (this)
      {
        doc = documentQueue.Dequeue();
      }
      return doc;
    }

  }

}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  class Program
  {
    static void Main()
    {
      var dm = new DocumentManager<Document>();
      dm.AddDocument(new Document("Title A", "Sample A"));
      dm.AddDocument(new Document("Title B", "Sample B"));

      dm.DisplayAllDocuments();

      if (dm.IsDocumentAvailable)
      {
        Document d = dm.GetDocument();
        Console.WriteLine(d.Content);
      }

    }
  }
}
View Code

GenericMethods

using System;

namespace Wrox.ProCSharp.Generics
{
  public interface IAccount
  {
    decimal Balance { get; }
    string Name { get; }
  }


  public class Account : IAccount
  {
    public string Name { get; private set; }
    public decimal Balance { get; private set; }

    public Account(string name, Decimal balance)
    {
      this.Name = name;
      this.Balance = balance;
    }
  }

}
View Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace Wrox.ProCSharp.Generics
{
  public static class Algorithm
  {
    public static decimal AccumulateSimple(IEnumerable<Account> source)
    {
      decimal sum = 0;
      foreach (Account a in source)
      {
        sum += a.Balance;
      }
      return sum;
    }

    public static decimal Accumulate<TAccount>(IEnumerable<TAccount> source)
        where TAccount : IAccount
    {
      decimal sum = 0;

      foreach (TAccount a in source)
      {
        sum += a.Balance;
      }
      return sum;
    }

    public static T2 Accumulate<T1, T2>(IEnumerable<T1> source, Func<T1, T2, T2> action)
    {
      T2 sum = default(T2);
      foreach (T1 item in source)
      {
        sum = action(item, sum);
      }
      return sum;
    }

  }

}
View Code
using System.Collections.Generic;

namespace Wrox.ProCSharp.Generics
{
  class Program
  {
    static void Main()
    {
      var accounts = new List<Account>()
      {
        new Account("Christian", 1500),
        new Account("Stephanie", 2200),
        new Account("Angela", 1800),
        new Account("Matthias", 2400)
      };

      decimal amount = Algorithm.AccumulateSimple(accounts);

      amount = Algorithm.Accumulate(accounts);

      amount = Algorithm.Accumulate<Account, decimal>(accounts, (item, sum) => sum += item.Balance);
    }
  }
}
View Code

LinkedListObjects

using System.Collections;

namespace Wrox.ProCSharp.Generics
{
  public class LinkedList : IEnumerable
  {
    public LinkedListNode First { get; private set; }
    public LinkedListNode Last { get; private set; }

    public LinkedListNode AddLast(object node)
    {
      var newNode = new LinkedListNode(node);
      if (First == null)
      {
        First = newNode;
        Last = First;
      }
      else
      {
        Last.Next = newNode;
        Last = newNode;
      }
      return newNode;
    }

    public IEnumerator GetEnumerator()
    {
      LinkedListNode current = First;
      while (current != null)
      {
        yield return current.Value;
        current = current.Next;
      }
    }
  }

}
View Code
namespace Wrox.ProCSharp.Generics
{
  public class LinkedListNode
  {
    public LinkedListNode(object value)
    {
      this.Value = value;
    }

    public object Value { get; private set; }

    public LinkedListNode Next { get; internal set; }
    public LinkedListNode Prev { get; internal set; }
  }

}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  class Program
  {
    static void Main()
    {
      var list1 = new LinkedList();
      list1.AddLast(2);
      list1.AddLast(4);
      list1.AddLast("6");

      foreach (int i in list1)
      {
        Console.WriteLine(i);
      }

    }
  }
}
View Code

LinkedListSample

using System.Collections;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Generics
{
  public class LinkedList<T> : IEnumerable<T>
  {
    public LinkedListNode<T> First { get; private set; }
    public LinkedListNode<T> Last { get; private set; }

    public LinkedListNode<T> AddLast(T node)
    {
      var newNode = new LinkedListNode<T>(node);
      if (First == null)
      {
        First = newNode;
        Last = First;
      }
      else
      {
        Last.Next = newNode;
        Last = newNode;
      }
      return newNode;
    }

    public IEnumerator<T> GetEnumerator()
    {
      LinkedListNode<T> current = First;

      while (current != null)
      {
        yield return current.Value;
        current = current.Next;
      }
    }

    IEnumerator IEnumerable.GetEnumerator()
    {
      return GetEnumerator();
    }
  }

}
View Code
namespace Wrox.ProCSharp.Generics
{
  public class LinkedListNode<T>
  {
    public LinkedListNode(T value)
    {
      this.Value = value;
    }

    public T Value { get; private set; }
    public LinkedListNode<T> Next { get; internal set; }
    public LinkedListNode<T> Prev { get; internal set; }
  }
}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  class Program
  {
    static void Main()
    {
      var list2 = new LinkedList<int>();
      list2.AddLast(1);
      list2.AddLast(3);
      list2.AddLast(5);

      foreach (int i in list2)
      {
        Console.WriteLine(i);
      }

      var list3 = new LinkedList<string>();
      list3.AddLast("2");
      list3.AddLast("four");
      list3.AddLast("foo");

      foreach (string s in list3)
      {
        Console.WriteLine(s);
      }


    }
  }
}
View Code

Specialization

using System;

namespace Wrox.ProCSharp.Generics
{

  public class MethodOverloads
  {
    public void Foo<T>(T obj)
    {
      Console.WriteLine("Foo<T>(T obj), obj type: {0}", obj.GetType().Name);
    }

    public void Foo(int x)
    {
      Console.WriteLine("Foo(int x)");
    }

    public void Bar<T>(T obj)
    {
      Foo(obj);
    }
  }

  class Program
  {
    static void Main()
    {
      var test = new MethodOverloads();
      test.Foo(33);
      test.Foo("abc");
      test.Bar(44);
    }
  }
}
View Code

Variance

using System;

namespace Wrox.ProCSharp.Generics
{
  public class ShapeDisplay : IDisplay<Shape>
  {
    public void Show(Shape s)
    {
      Console.WriteLine("{0} Width: {1}, Height: {2}", s.GetType().Name, s.Width, s.Height);
    }
  }
}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  public class Shape
  {
    public double Width { get; set; }
    public double Height { get; set; }

    public override string ToString()
    {
      return String.Format("Width: {0}, Height: {1}", Width, Height);
    }
  }
}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  public class RectangleCollection : IIndex<Rectangle>
  {
    private Rectangle[] data = new Rectangle[3] 
    {
      new Rectangle { Height=2, Width=5 },
      new Rectangle { Height=3, Width=7},
      new Rectangle { Height=4.5, Width=2.9}
    };

    private static RectangleCollection coll;
    public static RectangleCollection GetRectangles()
    {
      return coll ?? (coll = new RectangleCollection());
    }

    public Rectangle this[int index]
    {
      get
      {
        if (index < 0 || index > data.Length)
          throw new ArgumentOutOfRangeException("index");
        return data[index];
      }
    }
    public int Count
    {
      get
      {
        return data.Length;
      }
    }
  }
}
View Code
namespace Wrox.ProCSharp.Generics
{
  public class Rectangle : Shape
  {
  }
}
View Code
using System;

namespace Wrox.ProCSharp.Generics
{
  class Program
  {
    static void Main()
    {
      IIndex<Rectangle> rectangles = RectangleCollection.GetRectangles();
      IIndex<Shape> shapes = rectangles;

      for (int i = 0; i < shapes.Count; i++)
      {
        Console.WriteLine(shapes[i]);
      }


      IDisplay<Shape> shapeDisplay = new ShapeDisplay();
      IDisplay<Rectangle> rectangleDisplay = shapeDisplay;
      rectangleDisplay.Show(rectangles[0]);

    }

  }
}
View Code
namespace Wrox.ProCSharp.Generics
{
  // covariant
  public interface IIndex<out T>
  {
    T this[int index] { get; }
    int Count { get; }
  }
}
View Code
namespace Wrox.ProCSharp.Generics
{
  // contra-variant
  public interface IDisplay<in T>
  {
    void Show(T item);
  }
}
View Code

 

转载于:https://www.cnblogs.com/liuslayer/p/7017050.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值