KeyValuePair C#[通俗易懂]

KeyValuePair C#[通俗易懂]前几天自学了keyvaluepair,在网上找到一篇很好的Blog,所以转载过来共享。转载地址:http://www.cnblogs.com/C#KeyValuePairKeyValuePairstorestwovaluestogether.Itisasinglegenericstruct.TheKeyValuePairtypeinSyste…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

前几天自学了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

KeyValuePair C#[通俗易懂]

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.

转载于:https://www.cnblogs.com/Artemisblog/p/3706054.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/158819.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Visual Studio 15.8 Preview 3支持多点编辑功能

    Visual Studio 15.8 Preview 3支持多点编辑功能

  • 内存映射文件「建议收藏」

    内存映射文件「建议收藏」在做科研,实现一些大数据的算法的时候,经常要调用一些文件的I/O函数,在数据量很大的时候,除了设计的算法和数据结构的耗时以外,其实主要的耗时还是文件的I/O。因为一般常规的方法就是先读出磁盘文件的内容到内存中,然后修改,最后写回到磁盘上。读磁盘文件是要经过一次系统调用,先将文件的内容从磁盘拷贝到内核空间的一个缓冲区,然后再将这些数据拷贝到用户空间,实际上是两次数据拷贝。写回同样也需要经过两次数据拷

  • 数据库优化分库分表_数据库分库分表的好处

    数据库优化分库分表_数据库分库分表的好处一.数据切分关系型数据库本身比较容易成为系统瓶颈,单机存储容量、连接数、处理能力都有限。当单表的数据量达到1000W或100G以后,由于查询维度较多,即使添加从库、优化索引,做很多操作时性能仍下降严重。此时就要考虑对其进行切分了,切分的目的就在于减少数据库的负担,缩短查询时间。数据库分布式核心内容无非就是数据切分(Sharding),以及切分后对数据的定位、整合。数据切分就是将数据分散存储到多个数据库中,使得单一数据库中的数据量变小,通过扩充主机的数量缓解单一数据库的性能问题,从而达到提升数据库操作性

  • 9千字长文带你了解SpringBoot启动过程–史上最详细 SpringBoot启动流程-图文并茂

    9千字长文带你了解SpringBoot启动过程–史上最详细 SpringBoot启动流程-图文并茂来自面试官发自内审深处的灵魂拷问:“说一下springboot的启动流程”;一脸懵逼的面试者:“它简化了spring的配置,主要是因为有自动装配的功能,并且可以直接启动,因为它内嵌了tomcat容器”;面试官:“嗯,没错,这是它的一些概念,你还没回答我的问题,它是怎么启动的,启懂时都经过了哪些东西?”;一脸懵逼的面试者:“额~~~不知道额····,我用的很熟练,但是不知道它里面做了哪些事情!”;面试官:“了解内部原理是为了帮助我们做扩展,同时也是验证了一个人的学习能力,如果你想让自己的职业道路.

  • 怎么安装wget_Debian安装wget

    怎么安装wget_Debian安装wget第一步:执行wgetwww.baidu.com,若没有,会提示:-bash:wget:commandnotfound第二步:通过这个http://ftp.gnu.org/gnu/wget/下载wget的源代码wget-1.5.3.tar.gz第三步:通过命令行进入到下载后的文件夹,如:cdDownloads第四步:执行tar-zxvfwget-1.5.3.tar….

    2022年10月16日
  • 1174: 零起点学算法81——求整数绝对值

    1174: 零起点学算法81——求整数绝对值

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号