第十章 集合

由于iis的自动回收机制,不适用于ASP.NET程序

BitArraySample

代码:

图片 1图片 2

图片 3图片 4

using System;
using System.Collections;
using System.Collections.Specialized;
using System.Text;

namespace BitArraySample
{
  class Program
  {
    static void BitArrayDemo()
    {
      var bits1 = new BitArray(8);
      bits1.SetAll(true);
      bits1.Set(1, false);
      bits1[5] = false;
      bits1[7] = false;
      Console.Write("initialized: ");
      DisplayBits(bits1);
      Console.WriteLine();


      DisplayBits(bits1);
      bits1.Not();
      Console.Write(" not ");
      DisplayBits(bits1);
      Console.WriteLine();

      var bits2 = new BitArray(bits1);
      bits2[0] = true;
      bits2[1] = false;
      bits2[4] = true;
      DisplayBits(bits1);
      Console.Write(" or ");
      DisplayBits(bits2);
      Console.Write(" : ");
      bits1.Or(bits2);
      DisplayBits(bits1);
      Console.WriteLine();


      DisplayBits(bits2);
      Console.Write(" and ");
      DisplayBits(bits1);
      Console.Write(" : ");
      bits2.And(bits1);
      DisplayBits(bits2);
      Console.WriteLine();

      DisplayBits(bits1);
      Console.Write(" xor ");
      DisplayBits(bits2);
      bits1.Xor(bits2);
      Console.Write(" : ");
      DisplayBits(bits1);
      Console.WriteLine();
    }

    static void BitVectorDemo()
    {

      var bits1 = new BitVector32();
      int bit1 = BitVector32.CreateMask();
      int bit2 = BitVector32.CreateMask(bit1);
      int bit3 = BitVector32.CreateMask(bit2);
      int bit4 = BitVector32.CreateMask(bit3);
      int bit5 = BitVector32.CreateMask(bit4);

      bits1[bit1] = true;
      bits1[bit2] = false;
      bits1[bit3] = true;
      bits1[bit4] = true;
      Console.WriteLine(bits1);

      bits1[0xabcdef] = true;
      Console.WriteLine(bits1);


      int received = 0x79abcdef;

      var bits2 = new BitVector32(received);
      Console.WriteLine(bits2);
      // sections: FF EEE DDD CCCC BBBBBBBB AAAAAAAAAAAA
      BitVector32.Section sectionA = BitVector32.CreateSection(0xfff);
      BitVector32.Section sectionB = BitVector32.CreateSection(0xff, sectionA);
      BitVector32.Section sectionC = BitVector32.CreateSection(0xf, sectionB);
      BitVector32.Section sectionD = BitVector32.CreateSection(0x7, sectionC);
      BitVector32.Section sectionE = BitVector32.CreateSection(0x7, sectionD);
      BitVector32.Section sectionF = BitVector32.CreateSection(0x3, sectionE);



      Console.WriteLine("Section A: " + IntToBinaryString(bits2[sectionA], true));
      Console.WriteLine("Section B: " + IntToBinaryString(bits2[sectionB], true));
      Console.WriteLine("Section C: " + IntToBinaryString(bits2[sectionC], true));
      Console.WriteLine("Section D: " + IntToBinaryString(bits2[sectionD], true));
      Console.WriteLine("Section E: " + IntToBinaryString(bits2[sectionE], true));
      Console.WriteLine("Section F: " + IntToBinaryString(bits2[sectionF], true));


    }

    static string IntToBinaryString(int bits, bool removeTrailingZero)
    {
      var sb = new StringBuilder(32);

      for (int i = 0; i < 32; i++)
      {
        if ((bits & 0x80000000) != 0)
        {
          sb.Append("1");
        }
        else
        {
          sb.Append("0");
        }
        bits = bits << 1;
      }
      string s = sb.ToString();
      if (removeTrailingZero)
        return s.TrimStart('0');
      else
        return s;
    }

    static void Main()
    {
      // BitArrayDemo();
      BitVectorDemo();
    }


    static void DisplayBits(BitArray bits)
    {
      foreach (bool bit in bits)
      {
        Console.Write(bit ? 1 : 0);
      }
    }
  }
}
using System;
using System.Collections.Concurrent;
using System.Configuration;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace CommonDll
{
    /// <summary>
    /// 写日志类
    /// </summary>
    public class LogUtil
    {
        #region 字段
        public static string path = ConfigurationManager.AppSettings["LogPath"];
        public static int fileSize = 10 * 1024 * 1024; //日志分隔文件大小
        private static ConcurrentQueue<Tuple<string, DateTime>> queue = new ConcurrentQueue<Tuple<string, DateTime>>();
        #endregion

        #region 构造函数
        static LogUtil()
        {
            Task.Factory.StartNew(new Action(delegate()
            {
                StringBuilder log;
                string path;
                Tuple<string, DateTime> tuple;
                string item;

                while (true)
                {
                    log = new StringBuilder();
                    path = CreateLogPath();

                    while (queue.TryDequeue(out tuple))
                    {
                        item = string.Format(@"{0} {1}", tuple.Item2.ToString("yyyy-MM-dd HH:mm:ss.fff"), tuple.Item1);
                        log.AppendFormat("rn{0}", item);
                    }

                    if (log.Length > 0) WriteFile(log.ToString(2, log.Length - 2), path);
                    Thread.Sleep(100);
                }
            }));
        }
        #endregion

        #region 写文件
        /// <summary>
        /// 写文件
        /// </summary>
        public static void WriteFile(string log, string path)
        {
            try
            {
                if (!Directory.Exists(Path.GetDirectoryName(path)))
                {
                    Directory.CreateDirectory(Path.GetDirectoryName(path));
                }

                if (!File.Exists(path))
                {
                    using (FileStream fs = new FileStream(path, FileMode.Create)) { fs.Close(); }
                }

                using (FileStream fs = new FileStream(path, FileMode.Append, FileAccess.Write))
                {
                    using (StreamWriter sw = new StreamWriter(fs))
                    {
                        sw.WriteLine(log);
                        sw.Flush();
                    }
                    fs.Close();
                }
            }
            catch { }
        }
        #endregion

        #region 生成日志文件路径
        /// <summary>
        /// 生成日志文件路径
        /// </summary>
        public static string CreateLogPath()
        {
            int index = 0;
            string logPath;
            bool bl = true;
            do
            {
                index++;
                logPath = Path.Combine(path, "Log" + DateTime.Now.ToString("yyyyMMdd") + (index == 1 ? "" : "_" + index.ToString()) + ".txt");
                if (File.Exists(logPath))
                {
                    FileInfo fileInfo = new FileInfo(logPath);
                    if (fileInfo.Length < fileSize)
                    {
                        bl = false;
                    }
                }
                else
                {
                    bl = false;
                }
            } while (bl);

            return logPath;
        }
        #endregion

        #region 写错误日志
        /// <summary>
        /// 写错误日志
        /// </summary>
        public static void LogError(string log)
        {
            queue.Enqueue(new Tuple<string, DateTime>("[Error] " + log, DateTime.Now));
        }
        #endregion

        #region 写操作日志
        /// <summary>
        /// 写操作日志
        /// </summary>
        public static void Log(string log)
        {
            queue.Enqueue(new Tuple<string, DateTime>("[Info]  " + log, DateTime.Now));
        }
        #endregion

    }
}

View Code

View Code

ConcurrentSample

测试代码:

图片 5图片 6

图片 7图片 8

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Collections
{
  public class Info
  {
    public string Word { get; set; }
    public int Count { get; set; }
    public string Color { get; set; }

    public override string ToString()
    {
      return String.Format("{0} x: {1}", Count, Word);
    }
  }
}
private void button1_Click(object sender, EventArgs e)
{
    int n = 10000;
    DateTime dtStart = DateTime.Now;
    for (int i = 1; i <= n; i++)
    {
        ThreadPool.QueueUserWorkItem(new WaitCallback(delegate(object obj)
        {
            int j = (int)obj;
            LogUtil.Log("测试" + j.ToString("00000"));

            if (j == n)
            {
                double sec = DateTime.Now.Subtract(dtStart).TotalSeconds;
                MessageBox.Show(n + "条日志完成,耗时" + sec.ToString("0.000") + "秒");
            }
        }), i);
    }
}

View Code

View Code

图片 9图片 10

效果图:

using System;
using System.Collections.Concurrent;
using System.IO;
using System.Threading;
using System.Threading.Tasks;

namespace Wrox.ProCSharp.Collections
{
  class Program
  {
    static void Main()
    {
      // BlockingDemo();

      //BlockingDemoSimple();

      PipelineSample();

      Console.ReadLine();

    }

    private static void ReadFileNames(string path, BlockingCollection<string> output)
    {
      foreach (string filename in Directory.EnumerateFiles(path, "*.cs"))
      {
        output.Add(filename);
      }
      output.CompleteAdding();
    }

    private static void AddOrIncrementValue(string key, ConcurrentDictionary<string, int> dict)
    {
      bool success = false;
      while (!success)
      {
        int value;
        if (dict.TryGetValue(key, out value))
        {
          if (dict.TryUpdate(key, value + 1, value))
          {
            success = true;
          }
        }
        else
        {
          if (dict.TryAdd(key, 1))
          {
            success = true;
          }
        }
      }
    }



    private static async void LoadContent(BlockingCollection<string> input, ConcurrentDictionary<string, int> output)
    {
      foreach (var filename in input.GetConsumingEnumerable())
      {
        using (FileStream stream = File.OpenRead(filename))
        {
          var reader = new StreamReader(stream);
          string line = await reader.ReadLineAsync();
          string[] words = line.Split(' ', ';', 't');
          foreach (var word in words)
          {
            AddOrIncrementValue(word, output);
          }
        }
      }
    }

    private static void TransferContent(ConcurrentDictionary<string, int> input, BlockingCollection<Info> output)
    {
      foreach (var word in input.Keys)
        {
        int value;
        if (input.TryGetValue(word, out value))
        {
              output.Add(new Info { Word = word, Count = value });
        }
        }
    }
    private static void ShowContent(BlockingCollection<Info> input)
    {
      foreach (var item in input.GetConsumingEnumerable())
      {
        Console.WriteLine(item);
      }
    }

    private static async void PipelineSample()
    {
      BlockingCollection<string> coll1 = new BlockingCollection<string>();
      ConcurrentDictionary<string, int> coll2 = new ConcurrentDictionary<string,int>();
      BlockingCollection<Info> coll3 = new BlockingCollection<Info>();
      Task t1 = Task.Factory.StartNew(() => ReadFileNames(@"C:tempMvcApplication1MvcApplication1Controllers", coll1), TaskCreationOptions.LongRunning);
      Console.WriteLine("started stage 1");
      Task t2 = Task.Factory.StartNew(() => LoadContent(coll1, coll2), TaskCreationOptions.LongRunning);
      Console.WriteLine("started stage 2");
      await Task.WhenAll(t1, t2);
      Console.WriteLine("stage 1 and 2 completed");
      Task t3 = Task.Factory.StartNew(() => TransferContent(coll2, coll3), TaskCreationOptions.LongRunning);
      Task t4 = Task.Factory.StartNew(() => ShowContent(coll3), TaskCreationOptions.LongRunning);
      Console.WriteLine("stages 3 and 4 started");
      await Task.WhenAll(t3, t4);
      Console.WriteLine("all finished");


    }

    static void BlockingDemoSimple()
    {
      var sharedCollection = new BlockingCollection<int>();
      var events = new ManualResetEventSlim[2];
      var waits = new WaitHandle[2];
      for (int i = 0; i < 2; i++)
      {
        events[i] = new ManualResetEventSlim(false);
        waits[i] = events[i].WaitHandle;
      }

      var producer = new Thread(obj =>
      {
        var state = (Tuple<BlockingCollection<int>, ManualResetEventSlim>)obj;
        var coll = state.Item1;
        var ev = state.Item2;
        var r = new Random();

        for (int i = 0; i < 300; i++)
        {
          coll.Add(r.Next(3000));
        }
        ev.Set();
      });
      producer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[0]));

      var consumer = new Thread(obj =>
      {
        var state = (Tuple<BlockingCollection<int>, ManualResetEventSlim>)obj;
        var coll = state.Item1;
        var ev = state.Item2;

        for (int i = 0; i < 300; i++)
        {
          int result = coll.Take();
        }
        ev.Set();
      });
      consumer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[1]));

      if (!WaitHandle.WaitAll(waits))
        Console.WriteLine("wait failed");
      else
        Console.WriteLine("reading/writing finished");

    }

    static async void BlockingDemo()
    {
      const int taskCount = 10;
      ManualResetEventSlim[] events = new ManualResetEventSlim[taskCount];
      WaitHandle[] waits = new WaitHandle[taskCount];
      var consoleLock = new object();

      for (int task = 0; task < taskCount; task++)
      {
        events[task] = new ManualResetEventSlim(false);
        waits[task] = events[task].WaitHandle;
      }

      var sharedCollection = new BlockingCollection<int>();


      for (int task = 0; task < taskCount >> 1; task++)
      {

        var producer = new Task((state) =>
        {
          var coll = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item1;
          var wait = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item2;
          var r = new Random();
          for (int i = 0; i < 300; i++)
          {
            int data = r.Next(30000);
            if (!coll.TryAdd(data))
            {
              Console.WriteLine("**** couldn't add");
            }
            else
            {
              lock (consoleLock)
              {
                Console.ForegroundColor = ConsoleColor.Cyan;
                Console.Write(" {0} ", data);
                Console.ResetColor();
              }
            }
            Thread.Sleep(r.Next(40));
          }
          wait.Set();
        }, Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task]));

        producer.Start();
//        producer.Start(Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task]));
      }

      await Task.Delay(500); // give the producers a headstart


      for (int task = taskCount >> 1; task < taskCount; task++)
      {
        var consumer = new Task((state) =>
        {
          var coll = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item1;
          var wait = ((Tuple<BlockingCollection<int>, ManualResetEventSlim>)state).Item2;
          var r = new Random();
          for (int i = 0; i < 3000; i++)
          {
            int result;
            if (!coll.TryTake(out result))
            {
              Console.WriteLine("couldn't take");
            }
            else
            {
              lock (consoleLock)
              {
                Console.ForegroundColor = ConsoleColor.Red;
                Console.WriteLine(" {0} ", result);
                Console.ResetColor();
              }
            }

            Thread.Sleep(r.Next(40));
          }
          wait.Set();
        }, Tuple.Create<BlockingCollection<int>, ManualResetEventSlim>(sharedCollection, events[task]));
        consumer.Start();
      }

      if (!WaitHandle.WaitAll(waits))
        Console.WriteLine("error waiting...");

    }
  }
}

图片 11

View Code

 

DictionarySample

图片 12图片 13

using System;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Collections
{
  class Program
  {
    static void Main()
    {
      var employees = new Dictionary<EmployeeId, Employee>(31);

      var idTony = new EmployeeId("C3755");
      var tony = new Employee(idTony, "Tony Stewart", 379025.00m);
      employees.Add(idTony, tony);
      Console.WriteLine(tony);

      var idCarl = new EmployeeId("F3547");
      var carl = new Employee(idCarl, "Carl Edwards", 403466.00m);
      employees.Add(idCarl, carl);
      Console.WriteLine(carl);

      var idKevin = new EmployeeId("C3386");
      var kevin = new Employee(idKevin, "Kevin Harwick", 415261.00m);
      employees.Add(idKevin, kevin);
      Console.WriteLine(kevin);

      var idMatt = new EmployeeId("F3323");
      var matt = new Employee(idMatt, "Matt Kenseth", 1589390.00m);
      employees[idMatt] = matt;
      Console.WriteLine(matt);

      var idBrad = new EmployeeId("D3234");
      var brad = new Employee(idBrad, "Brad Keselowski", 322295.00m);
      employees[idBrad] = brad;
      Console.WriteLine(brad);



      while (true)
      {
        Console.Write("Enter employee id (X to exit)> ");
        var userInput = Console.ReadLine();
        userInput = userInput.ToUpper();
        if (userInput == "X") break;

        EmployeeId id;
        try
        {
          id = new EmployeeId(userInput);


          Employee employee;
          if (!employees.TryGetValue(id, out employee))
          {
            Console.WriteLine("Employee with id {0} does not exist", id);
          }
          else
          {
            Console.WriteLine(employee);
          }
        }
        catch (EmployeeIdException ex)
        {
          Console.WriteLine(ex.Message);
        }
      }

    }
  }
}

View Code

图片 14图片 15

using System;
using System.Diagnostics.Contracts;

namespace Wrox.ProCSharp.Collections
{
  [Serializable]
  public class EmployeeIdException : Exception
  {
    public EmployeeIdException(string message) : base(message) { }
  }

  [Serializable]
  public struct EmployeeId : IEquatable<EmployeeId>
  {
    private readonly char prefix;
    private readonly int number;

    public EmployeeId(string id)
    {
      Contract.Requires<ArgumentNullException>(id != null);

      prefix = (id.ToUpper())[0];
      int numLength = id.Length - 1;
      try
      {
        number = int.Parse(id.Substring(1, numLength > 6 ? 6 : numLength));
      }
      catch (FormatException)
      {
        throw new EmployeeIdException("Invalid EmployeeId format");
      }
    }

    public override string ToString()
    {
      return prefix.ToString() + string.Format("{0,6:000000}", number);
    }

    public override int GetHashCode()
    {
      return (number ^ number << 16) * 0x15051505;
    }

    public bool Equals(EmployeeId other)
    {
      if (other == null) return false;

      return (prefix == other.prefix && number == other.number);
    }

    public override bool Equals(object obj)
    {
      return Equals((EmployeeId)obj);
    }

    public static bool operator ==(EmployeeId left, EmployeeId right)
    {
      return left.Equals(right);
    }

    public static bool operator !=(EmployeeId left, EmployeeId right)
    {
      return !(left == right);
    }
  }

}

View Code

图片 16图片 17

using System;

namespace Wrox.ProCSharp.Collections
{
  [Serializable]
  public class Employee
  {
    private string name;
    private decimal salary;
    private readonly EmployeeId id;

    public Employee(EmployeeId id, string name, decimal salary)
    {
      this.id = id;
      this.name = name;
      this.salary = salary;
    }

    public override string ToString()
    {
      return String.Format("{0}: {1, -20} {2:C}",
            id.ToString(), name, salary);
    }
  }

}

View Code

ImmutableCollectionsSample

图片 18图片 19

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

namespace ImmutableCollectionsSample
{
  class Program
  {
    static void Main(string[] args)
    {
      // ArraySample();
      ListSample();
      Console.ReadKey();
    }

    private static void ListSample()
    {
      List<Account> accounts = new List<Account>() {
        new Account {
          Name = "Scrooge McDuck", 
          Amount = 667377678765m
        },
        new Account {
          Name = "Donald Duck",
          Amount = -200m
        },
       new Account {
         Name = "Ludwig von Drake",
         Amount = 20000m
        }};
      ImmutableList<Account> immutableAccounts = accounts.ToImmutableList();

      ImmutableList<Account>.Builder builder = immutableAccounts.ToBuilder();
      for (int i = 0; i < builder.Count; i++)
      {
        Account a = builder[i];
        if (a.Amount > 0)
        {
          builder.Remove(a);
        }
      }

      ImmutableList<Account> overdrawnAccounts = builder.ToImmutable();


      foreach (var item in overdrawnAccounts)
      {
        Console.WriteLine("{0} {1}", item.Name, item.Amount);
      }

    }

    private static void ArraySample()
    {
      ImmutableArray<string> a1 = ImmutableArray.Create<string>();
      ImmutableArray<string> a2 = a1.Add("Williams");
      ImmutableArray<string> a3 = a2.Add("Ferrari").Add("Mercedes").Add("Red Bull Racing");
      foreach (var item in a3)
      {
        Console.WriteLine(item);
      }

    }
  }
}

View Code

图片 20图片 21

namespace ImmutableCollectionsSample
{
  public class Account
  {
    public string Name { get; set; }
    public decimal Amount { get; set; }
  }
}

View Code

LinkedListSample

图片 22图片 23

using System;
namespace Wrox.ProCSharp.Collections
{
  class Program
  {
    static void Main()
    {
      PriorityDocumentManager pdm = new PriorityDocumentManager();
      pdm.AddDocument(new Document("one", "Sample", 8));
      pdm.AddDocument(new Document("two", "Sample", 3));
      pdm.AddDocument(new Document("three", "Sample", 4));
      pdm.AddDocument(new Document("four", "Sample", 8));
      pdm.AddDocument(new Document("five", "Sample", 1));
      pdm.AddDocument(new Document("six", "Sample", 9));
      pdm.AddDocument(new Document("seven", "Sample", 1));
      pdm.AddDocument(new Document("eight", "Sample", 1));

      pdm.DisplayAllNodes();
      Console.ReadKey();
    }
  }
}

View Code

图片 24图片 25

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace Wrox.ProCSharp.Collections
{
  public class PriorityDocumentManager
  {
    private readonly LinkedList<Document> documentList;

    // priorities 0.9
    private readonly List<LinkedListNode<Document>> priorityNodes;

    public PriorityDocumentManager()
    {
      documentList = new LinkedList<Document>();

      priorityNodes = new List<LinkedListNode<Document>>(10);
      for (int i = 0; i < 10; i++)
      {
        priorityNodes.Add(new LinkedListNode<Document>(null));
      }
    }

    public void AddDocument(Document d)
    {
      //Contract.Requires<ArgumentNullException>(d != null, "argument d must not be null");
      if (d == null) throw new ArgumentNullException("d");

      AddDocumentToPriorityNode(d, d.Priority);
    }

    private void AddDocumentToPriorityNode(Document doc, int priority)
    {
      //Contract.Requires<ArgumentException>(priority >= 0 && priority < 10, "priority value must be between 0 and 9");
      if (priority > 9 || priority < 0)
          throw new ArgumentException("Priority must be between 0 and 9");

      if (priorityNodes[priority].Value == null)
      {
        --priority;
        if (priority >= 0)
        {
          // check for the next lower priority
          AddDocumentToPriorityNode(doc, priority);
        }
        else // now no priority node exists with the same priority or lower
        // add the new document to the end
        {
          documentList.AddLast(doc);
          priorityNodes[doc.Priority] = documentList.Last;
        }
        return;
      }
      else // a priority node exists
      {
        LinkedListNode<Document> prioNode = priorityNodes[priority];
        if (priority == doc.Priority)
        // priority node with the same priority exists
        {
          documentList.AddAfter(prioNode, doc);

          // set the priority node to the last document with the same priority
          priorityNodes[doc.Priority] = prioNode.Next;
        }
        else // only priority node with a lower priority exists
        {
          // get the first node of the lower priority
          LinkedListNode<Document> firstPrioNode = prioNode;

          while (firstPrioNode.Previous != null &&
             firstPrioNode.Previous.Value.Priority == prioNode.Value.Priority)
          {
            firstPrioNode = prioNode.Previous;
            prioNode = firstPrioNode;
          }

          documentList.AddBefore(firstPrioNode, doc);

          // set the priority node to the new value
          priorityNodes[doc.Priority] = firstPrioNode.Previous;
        }
      }
    }

    public void DisplayAllNodes()
    {
      foreach (Document doc in documentList)
      {
        Console.WriteLine("priority: {0}, title {1}", doc.Priority, doc.Title);
      }
    }

    // returns the document with the highest priority
    // (that's first in the linked list)
    public Document GetDocument()
    {
      Document doc = documentList.First.Value;
      documentList.RemoveFirst();
      return doc;
    }

  }

}

View Code

图片 26图片 27

namespace Wrox.ProCSharp.Collections
{
  public class Document
  {
    public string Title { get; private set; }
    public string Content { get; private set; }
    public byte Priority { get; private set; }

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

}

View Code

ListSamples

图片 28图片 29

using System;
using System.Collections.Generic;

namespace Wrox.ProCSharp.Collections
{
  public enum CompareType
  {
    FirstName,
    LastName,
    Country,
    Wins
  }

  public class RacerComparer : IComparer<Racer>
  {
    private CompareType compareType;
    public RacerComparer(CompareType compareType)
    {
      this.compareType = compareType;
    }

    public int Compare(Racer x, Racer y)
    {
      if (x == null && y == null) return 0;
      if (x == null) return -1;
      if (y == null) return 1;

      int result;
      switch (compareType)
      {
        case CompareType.FirstName:
          return string.Compare(x.FirstName, y.FirstName);
        case CompareType.LastName:
          return string.Compare(x.LastName, y.LastName);
        case CompareType.Country:
          result = string.Compare(x.Country, y.Country);
          if (result == 0)
            return string.Compare(x.LastName, y.LastName);
          else
            return result;
        case CompareType.Wins:
          return x.Wins.CompareTo(y.Wins);
        default:
          throw new ArgumentException("Invalid Compare Type");
      }
    }
  }

}

View Code

图片 30图片 31

using System;

namespace Wrox.ProCSharp.Collections
{
  [Serializable]
  public class Racer : IComparable<Racer>, IFormattable
  {
    public int Id { get; private set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Country { get; set; }
    public int Wins { get; set; }

    public Racer(int id, string firstName, string lastName, string country)
      : this(id, firstName, lastName, country, wins: 0)
    {
    }
    public Racer(int id, string firstName, string lastName, string country, int wins)
    {
      this.Id = id;
      this.FirstName = firstName;
      this.LastName = lastName;
      this.Country = country;
      this.Wins = wins;
    }

    public override string ToString()
    {
      return String.Format("{0} {1}", FirstName, LastName);
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {
      if (format == null) format = "N";
      switch (format.ToUpper())
      {
        case null:
        case "N": // name
          return ToString();
        case "F": // first name
          return FirstName;
        case "L": // last name
          return LastName;
        case "W": // Wins
          return String.Format("{0}, Wins: {1}", ToString(), Wins);
        case "C": // Country
          return String.Format("{0}, Country: {1}", ToString(), Country);
        case "A": // All
          return String.Format("{0}, {1} Wins: {2}", ToString(), Country, Wins);
        default:
          throw new FormatException(String.Format(formatProvider,
                "Format {0} is not supported", format));
      }
    }

    public string ToString(string format)
    {
      return ToString(format, null);
    }

    public int CompareTo(Racer other)
    {
      if (other == null) return -1;
      int compare = string.Compare(this.LastName, other.LastName);
      if (compare == 0)
        return string.Compare(this.FirstName, other.FirstName);
      return compare;
    }
  }

}

View Code

图片 32图片 33

using System.Collections.Generic;

namespace Wrox.ProCSharp.Collections
{
    class Program
    {
        static void Main()
        {
            var graham = new Racer(7, "Graham", "Hill", "UK", 14);
            var emerson = new Racer(13, "Emerson", "Fittipaldi", "Brazil", 14);
            var mario = new Racer(16, "Mario", "Andretti", "USA", 12);

            var racers = new List<Racer>(20) { graham, emerson, mario };

            racers.Add(new Racer(24, "Michael", "Schumacher", "Germany", 91));
            racers.Add(new Racer(27, "Mika", "Hakkinen", "Finland", 20));

            racers.AddRange(new Racer[] {
               new Racer(14, "Niki", "Lauda", "Austria", 25),
               new Racer(21, "Alain", "Prost", "France", 51)});

            var racers2 = new List<Racer>(new Racer[] {
               new Racer(12, "Jochen", "Rindt", "Austria", 6),
               new Racer(22, "Ayrton", "Senna", "Brazil", 41) });



        }
    }
}

View Code

LookupSample

图片 34图片 35

using System;

namespace Wrox.ProCSharp.Collections
{
  [Serializable]
  public class Racer : IComparable<Racer>, IFormattable
  {
    public int Id { get; private set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Country { get; set; }
    public int Wins { get; set; }

    public Racer(int id, string firstName, string lastName, string country = null, int wins = 0)
    {
      this.Id = id;
      this.FirstName = firstName;
      this.LastName = lastName;
      this.Country = country;
      this.Wins = wins;
    }

    public override string ToString()
    {
      return String.Format("{0} {1}", FirstName, LastName);
    }

    public string ToString(string format, IFormatProvider formatProvider)
    {
      if (format == null) format = "N";
      switch (format.ToUpper())
      {
        case "N": // name
          return ToString();
        case "F": // first name
          return FirstName;
        case "L": // last name
          return LastName;
        case "W": // Wins
          return String.Format("{0}, Wins: {1}", ToString(), Wins);
        case "C": // Country
          return String.Format("{0}, Country: {1}", ToString(), Country);
        case "A": // All
          return String.Format("{0}, {1} Wins: {2}", ToString(), Country, Wins);
        default:
          throw new FormatException(String.Format(formatProvider,
                "Format {0} is not supported", format));
      }
    }

    public string ToString(string format)
    {
      return ToString(format, null);
    }

    public int CompareTo(Racer other)
    {
      int compare = this.LastName.CompareTo(other.LastName);
      if (compare == 0)
        return this.FirstName.CompareTo(other.FirstName);
      return compare;
    }
  }

}

本文由金沙官网线上发布于编程,转载请注明出处:第十章 集合

您可能还会对下面的文章感兴趣: