zoukankan      html  css  js  c++  java
  • KeyValuePair C#

    前几天自学了keyvaluepair,在网上找到一篇很好的Blog ,所以转载过来共享。

    转载地址:http://www.cnblogs.com/

    C# KeyValuePair

    KeyValuePair: Key and Value properties

    KeyValuePair stores two values together. It is a single generic struct. The KeyValuePair type in System.Collections.Generic is simple and always available. It is used internally in Dictionary.

    Example

    First, this example uses KeyValuePair in a List, which is also in System.Collections.Generic. This is useful for storing pairs of values in a single List. You could use two separate Lists, but that can complicate matters.

    ListList

    Here:We initialize a new List of type KeyValuePair.
    This shows the required syntax form.

    Note:Inside the brackets in the KeyValuePair, there are two types separated by a comma (string, int).

    StringsInt

    Program that uses KeyValuePair: C#
    
    using System;
    using System.Collections.Generic;
    
    class Program
    {
        static void Main()
        {
    	// Shows a List of KeyValuePairs.
    	var list = new List<KeyValuePair<string, int>>();
    	list.Add(new KeyValuePair<string, int>("Cat", 1));
    	list.Add(new KeyValuePair<string, int>("Dog", 2));
    	list.Add(new KeyValuePair<string, int>("Rabbit", 4));
    
    	foreach (var element in list)
    	{
    	    Console.WriteLine(element);
    	}
        }
    }
    
    Output
    
    [Cat, 1]
    [Dog, 2]
    [Rabbit, 4]

    Key: used to access value

    Also, we can create a new KeyValuePair with its constructor. The constructor is shown in the List.Add calls. The KeyValuePair's constructor returns the new KeyValuePair, and that instance is added.

    List Add

    Note:Instead of a List, you could use an array here. You can specify the KeyValuePair<string, int> as the type of the array.

    Example 2

    Return keyword

    Often, you need to return two separate values from a method. You can do this easily with KeyValuePair. You must specify the exact type in the return value, and then return the new KeyValuePair in the method body.

    Tip:This is clearer than a two-element array.
    Consider out or ref parameters instead.

    OutRef

    Program that returns two values: C#
    
    using System;
    using System.Collections.Generic;
    
    class Program
    {
        static void Main()
        {
    	Console.WriteLine(GetNames());
        }
    
        static KeyValuePair<string, string> GetNames()
        {
    	// Gets collection of first and last name.
    	string firstName = "William";
    	string lastName = "Gates";
    	return new KeyValuePair<string, string>(firstName, lastName);
        }
    }
    
    Output
    
    [William, Gates]

    Error

    Warning: exclamation mark

    When using KeyValuePair in your program, you will likely get this error at some point. The C# compiler doesn't allow you to assign the Key and Value properties. This must be assigned in the constructor.

    Error:
    
    Property or indexer 'System.Collections.Generic.KeyValuePair...Key'
    cannot be assigned to--it is read-only.

    Dictionary loop

    Loop

    Probably the most popular usage of KeyValuePair is in a loop over a Dictionary. The Dictionary collection in C# has an enumerator that returns each key and value in a KeyValuePair, one at a time. Examples are available.

    Dictionary

    Also:An improved syntax could be to use the var keyword with the foreach loop over your Dictionary. This shortens the syntax.

    Var

    Sort

    Sorted letters: A to Z

    How can you sort a collection of KeyValuePair instances? You can implement a custom sorting Comparison method. We use the delegate method syntax. The linked tutorial contains information on this approach.

    Sort KeyValuePair List

    Also, you may use KeyValuePair in a List to create two parallel Lists. These are easily sorted, keeping both values together. This site has an example of an accurate shuffle algorithm with KeyValuePair and List.

    Shuffle Array

    Implementation

    Framework: NET

    You should know the basic layout of the KeyValuePair struct. Here, we see the internal code. The KeyValuePair has two private fields, and two public properties that retrieve the values of those fields.

    Property

    Implementation of KeyValuePair: C#
    
    [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct KeyValuePair<TKey, TValue>
    {
        private TKey key;
        private TValue value;
        public KeyValuePair(TKey key, TValue value);
        public TKey Key { get; }
        public TValue Value { get; }
        public override string ToString();
    }

    ToString

    String type

    The ToString method is useful. When you want to display the values, simply call ToString or pass the KeyValuePair to Console.Write or Console.WriteLine. This will implicitly call ToString. Internally, ToString uses a StringBuilder.

    Console.WriteStringBuilder

    Performance

    Performance optimization

    Is there any advantage to using custom structs instead of KeyValuePair generic types? Conceptually, the two approaches should be precisely equivalent in functionality, but there are some differences in performance.

    KeyValuePair performance
        KeyValuePair influenced how the method was inlined.
    
    Method that uses normal struct: 0.32 ns
    Method that uses KeyValuePair:  4.35 ns

    Next, we figure out what we are comparing. It is always possible to use custom structs with two fields instead of a KeyValuePair with those types. My question was whether this is ever worthwhile doing.

    Struct

    Version 1
    
    struct CustomPair
    {
        public int Key;
        public string Value;
    }
    
    Version 2
    
    KeyValuePair<int, string>

    Next, we look at a benchmark that compares the two structs. You would think that the .NET Framework would compile the two methods in the exactly same way, but I found the methods are inlined in different ways.

    Overload Method

    Program that tests KeyValuePair performance
    
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    
    struct CustomPair
    {
        public int Key;
        public string Value;
    }
    
    class Program
    {
        const int _max = 300000000;
        static void Main()
        {
    	CustomPair p1;
    	p1.Key = 4;
    	p1.Value = "perls";
    	Method(p1);
    
    	KeyValuePair<int, string> p2 = new KeyValuePair<int, string>(4, "perls");
    	Method(p2);
    
    	for (int a = 0; a < 5; a++)
    	{
    	    var s1 = Stopwatch.StartNew();
    	    for (int i = 0; i < _max; i++)
    	    {
    		Method(p1);
    		Method(p1);
    	    }
    	    s1.Stop();
    	    var s2 = Stopwatch.StartNew();
    	    for (int i = 0; i < _max; i++)
    	    {
    		Method(p2);
    		Method(p2);
    	    }
    	    s2.Stop();
    
    	    Console.WriteLine(((double)(s1.Elapsed.TotalMilliseconds * 1000000) /
    		_max).ToString("0.00 ns"));
    	    Console.WriteLine(((double)(s2.Elapsed.TotalMilliseconds * 1000000) /
    		_max).ToString("0.00 ns"));
    	}
    	Console.Read();
        }
    
        static int Method(CustomPair pair)
        {
    	return pair.Key + pair.Value.Length;
        }
    
        static int Method(KeyValuePair<int, string> pair)
        {
    	return pair.Key + pair.Value.Length;
        }
    }
    
    Result
    
    0.32 ns
    4.35 ns
    0.32 ns
    4.34 ns
    0.32 ns
    4.36 ns
    0.32 ns
    4.35 ns
    0.32 ns
    4.36 ns

    Just-in-time compiler: JIT

    I looked inside the two Method implementations in the IL Disassembler tool. They have the same code size. But in the KeyValuePair version, the call instruction is used instead of ldfld because KeyValuePair uses properties.

    IL Disassembler

    After C# compilation, the program is JIT-compiled during runtime. The behavior of the inliner is sometimes hard to determine. Extra members that need inlining sometimes influence the inliner and end up reducing performance.

    JIT Method Test

    Tip:It is possible to improve performance by replacing a KeyValuePair with a regular struct.

    Benchmark

    Discussion

    Object-oriented programming

    In some contexts—such as internal method code—using KeyValuePair is convenient and simple. But using a class or struct you define yourself can definitely enhance the object-orientation of your program.

    Therefore:I suggest you prefer classes when the usage is not trivial. This improves object-oriented design.

    ClassObject-Oriented Programming

    Tuple. Another option now available in the .NET Framework is the Tuple type. You can have a two-element Tuple. A Tuple is a class, not a struct. It can also have many more items in it.

    Tuple

    Summary

    We saw examples of using KeyValuePair in the C# language, and also looked into its internals in the .NET Framework. Lists and Dictionaries are ideal companions for KeyValuePairs. We returned the collection from methods.

  • 相关阅读:
    MySQL · 引擎特性 · InnoDB崩溃恢复
    MySQL · 引擎特性 · InnoDB Buffer Pool
    MySQL · 引擎特性 · InnoDB IO子系统
    MySQL · 引擎特性 · InnoDB 同步机制
    docker基本操作命令
    IIS日志导出mysql
    Win10 MySQL Community Server 8.0.17安装
    win10 TortoiseGit 图标不显示
    window环境配置nginx
    windows openssh安装
  • 原文地址:https://www.cnblogs.com/Artemisblog/p/3706054.html
Copyright © 2011-2022 走看看