ãã®è¨äºã¯ãC# Advent Calendar 2024 ãã«åå ãã¦ãã¾ããã·ãªã¼ãºï¼ã®ï¼ï¼æï¼ï¼æ¥ã®å
容ã§ãã
C# ã®ããã©ã¼ãã³ã¹é«éå ã«é¢ãããã¨ãå¦ç¿ããå
容ã§ããä¸è¨ã®ãã㪠Tips ããã£ãã®ã§ãå人çã«ãµã³ãã«ã³ã¼ããæ¸ããã調ã¹ãããã¦å¦ç¿ããå
容ã«ãªãã¾ããï¼å
容ã¯å çããæªè¨è¼ãããï¼
ãã¤ã³ãã¯ãã½ããã¦ã§ã¢ã¯éãã¦å°ããã¨ã¯ãªãã
ãã¼ãã¢ãã±ã¼ã·ã§ã³ ï¼å²ãå½ã¦ï¼ãï¼é¿ãããã¨ããã¯ï¼é¿ãã
ã¡ã¢ãªã®åå©ç¨ã¨ã¹ã¿ãã¯é åã®æ´»ç¨ãå¾¹åº
éåæ I/O ã使ã
CPU ã¯é«ä¾¡ãªãªã½ã¼ã¹ãªã®ã§ãå¾
ã¡æéãä¸ãã使ãåã
è¨ç®å¹çãä¸ãã
C# ã«ãããã¡ã¢ãªç®¡çæ¹æ³ã¯å¤åãã¹ã¿ãã¯ãã¨åç
§åããã¼ããã®ï¼ç¨®é¡ãããã¾ããä¸è¬çã«ãã¼ãã®é åã® "確ä¿" ã¯ã¹ã¿ãã¯ã¨æ¯ã¹ãã¨éããå¦çã«ãªãã¾ãã
å¥ã®è¨ãæ¹ã§ã®ãã¤ã³ãï¼
å®è£
æãããããã¨ãã£ã¦æããªã
ããéãã³ã¼ããã¹/å
±éã©ã¤ãã©ãªã¯ç¹ã«ç®ãåãã
éãã³ã¼ããæ¸ãçãã¤ãã
ç·´ç¿ã¨æã£ã¦åãçµãã»ãããã
èªãã¨ãã®ããã®ç¨èªã¡ã¢ï¼
å¤åã®å©ç¹ã¯ãã¹ã¿ãã¯ã«å¤ãç½®ãï¼ãã¼ãã使ããªãï¼ãã¨ã«ããæ§è½åä¸ã§ããããã¯ã¹åï¼ãã¼ãé åã®ç¢ºä¿ï¼ãèµ·ããã¨ãå¤åã®å©ç¹ã¯å¤±ããã¾ãã
ããã©ã¼ãã³ã¹ã«å½±é¿ã®å¤§ãã絶対ã«å®ãã¹ããã¨
ã³ã¬ã¯ã·ã§ã³ã®åããã
List åãé
ååã«å¤æãããä¸å¯é¿ãªçç±ããªããªãç¡é§ãªã¡ã¢ãªã³ãã¼ãçºçããããé©åã§ã¯ãªãã
List<int > values = [1 , 2 , 3 , 4 ];
DoSomething(values.ToArray());
void DoSomething(int [] values)
{
...
}
ãã ããå¾è¿°ã® AsSpan()
ï¼Span<T>
ï¼ã¯ãéã«æé©åã«ãªããã¨ãããã¾ãã
int [] array = { 0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 };
foreach (var i in array.AsSpan()[2..6 ]))
{
...
}
ã«ã¼ãå
ã®ç·å½¢æ¢ç´¢
ã³ã¬ã¯ã·ã§ã³ã®ãã¼ã¿æ°ãèãã¦ããããããã¼ã¿ãããã¨ãã¯ã©ãããã°åå¾ãéãã®ããFirst ã¯ç·å½¢æ¢ç´¢ãªã®ã§å¹çã¨ããããªãããã
foreach (var sample in samples)
{
var bad = sample.First(p => p.id == id);
var good = sample[id];
}
ç·å½¢æ¢ç´¢â¦â¦å
é ããé çªã«æ¯è¼ãè¡ããè¦ã¤ããã°çµäºããã
ã³ã¬ã¯ã·ã§ã³ã®åæ容éãæå®
åçãªãããã¡æ¡å¼µã¯ããªãã¹ãé¿ããã
åæ容é (capacity) ãæå®ããªããã°ãæå¾ã®è¦ç´ ã追å ããã¨ãã«ï¼åã®å
é¨ãããã¡ç¢ºä¿ã¨å
¨è¦ç´ ã®ã³ãã¼ãçºçããããéå¹çã
ããã©ã¼ãã³ã¹ã«æªå½±é¿ãããã®ã¯ã Count 3 ã®ã¿ã¤ãã³ã°ãã³ã¬ã¯ã·ã§ã³ã®å®¹éãä¸ããããã«ãæ¢åã³ã¬ã¯ã·ã§ã³ããæ°ããã³ã¬ã¯ã·ã§ã³ã«ã³ãã¼ãçºçããã
int [] values = [1 , 2 , 3 , 4 ];
var list = new List<int >(capacity: values.Length / 2 );
foreach (var x in values)
{
list.Add(x);
Console.WriteLine($"Capacity: { list.Capacity} , Count: { list.Count} " );
}
Capacity: 2, Count: 1
Capacity: 2, Count: 2
Capacity: 4, Count: 3
Capacity: 4, Count: 4
Result 㨠Wait ã¯ããã
ã¹ã¬ããã®å¦çããããã¯ããã®ã§ãã¹ã¬ãããå æããããæ³åãã¦ãããããããããã㯠ããããã
çµæçã«ãªã½ã¼ã¹å¹çãä½ä¸ããã
public int DoBadSomething()
{
var result = CallAsync().Result;
return result + 1 ;
}
public async Task<int > DoGoodSomething()
{
var result = await CallAsync();
return result + 1 ;
}
æ¬è³ªçã§ã¯ãªããã©ãããããã㯠ãé¿ãã対çã®ä¸ä¾ãå¦çããã¹ã¬ãããå¤ãã¦å¾
ã¤ãã©ãã¹ã¬ãããå¹ççã«å©ç¨ããã¦ããã¨ã¯è¨ããªãã
public int DoBadSomethingSafe()
{
var result = CallAsync().ConfigureAwait(false ).GetAwaiter().GetResult();
return result + 1 ;
}
ç°å¢
æéã®éçº/å®è¡ç°å¢
ææ°ã® .NET ãå©ç¨ãã¦ãããã¨ã
.NET Framework ãããä½åãéããC# 7.x 以éã¯ãããã©ã¼ãã³ã¹ãæèããæ¹åãå¤ããåºæ¬çã«ã¯å¾æ¹äºæ ãããã®ã§æ´æ°ãã¦ææ°ã®è¨èªæ©è½ã使ãã
MemoryPack
MessagePack for C#
FastEnum
æ§é ä½
Understanding C# Struct All Things ãã
æ§é ä½ã®åªä½æ§
ã¬ãã¼ã¸ã³ã¬ã¯ã·ã§ã³ ã®é »åº¦ãä¸ãã
GC ã®å®è¡æã¯ããã©ã¼ãã³ã¹ãç¬éçã«å¤§ããä½ä¸ãã
ç¹ã« Unity ã®ãããªãã¬ã¼ã ãã¼ã¹ã®ã¢ããªã¯æ°ãã¤ãã
ã¡ã³ãã¼ã¸ã®ã¢ã¯ã»ã¹ãé«éã«ãªã
å¤åï¼ã¹ã¿ãã¯é åã«ããã®ã§ããã®ã¾ã¾ç´ã«ã¢ã¯ã»ã¹å¯è½
åç
§åï¼ãã¼ãé åããå¤ããã©ã£ã¦ã¢ã¯ã»ã¹ãã
æã£ããããæ§é ä½ã®æåã¯ãè¨èªä»æ§ã®ç¥èãå¿
è¦ãªã¨ãããããã¾ããããã¤ãã®ä½æ³ãç¥ã£ã¦ãããã¨ã§ãå¹çåãããæãã§ãã
æ§é ä½ã®æ¬ ç¹
é«é »åº¦ã§å¤ã®ã³ãã¼ãçºçãã
å¼æ°/æ»ãå¤/å¤æ°ã¸ã®ä»£å
¥/é¢æ°å¼ã³åºã
ãµã¤ãºã®å¤§ããæ§é ä½ã®å ´åã¯ãéã«ã³ã¹ãã«ãªãï¼16 bytes ç®éï¼
ç¶æ¿/å¤æ
ãã§ããªã
ç¾ç¶ã¯ interface + æ¡å¼µã¡ã½ãããé§ä½¿ãã
ã¤ã³ã¿ã¼ãã§ã¼ã¹ä»¥å¤ã®ç¶æ¿ãã§ããªãçç±ãèããã¨ãstruct ã¯ãã¡ã¢ãªããããã³ã° ããæ§é ã ãããã¨ããèãæ¹ãããããããã¨æãã¾ããè£ä»ãã¨ã㦠StructLayout
ã¯ããã©ã«ãã 㨠Sequential ã§ããï¼class ã®ããã«ï¼ãã¼ã¿ã®ä¸¦ã³ãã¢ã©ã¤ã¡ã³ãã«ããããæé©åã¯ããã¾ãããå¤åã¨ãã¦ãåºå®ãµã¤ãºãå®ããã¨ãåªå
ãããã¨èãããã¨ãã§ãã¾ãã
ã¤ã³ã¿ã¼ãã§ã¼ã¹ãä»ä¸ã§ããã®ã¯ãã¡ã¢ãªæ§é ã«å½±é¿ãä¸ããã«å¤æ§æ§ã追å ããã ãã ããã§ãããã¨ãã¨ãï¼£è¨èªã®æ§é ä½ã¯å®å
¨ãªå¤åã§ã¡ã½ãããä½ããã¨ãã§ãã¾ããã§ãããããããï¼£ï¼ã®æ§é ä½ã¯æåãããå¤åã¨ãã¦ã®ç¹æ§ãæã¡ã¤ã¤ã¡ã½ãããæã¦ã¾ããåãçç±ã ã¨èãã¦ãã¾ãã
åç
§æ¸¡ã
æ§è½å£åã«ç´çµããã³ãã¼ãæå¶ãããæ§é ä½ã®ãµã¤ãºã大ããã¨ãã¯æ¤è¨ããã
å
·ä½çã«ããã¨ä»¥ä¸ã®ä¾ã 㨠a
㯠PassThrough
ã¡ã½ããã«åç
§ã渡ãã¦ã㦠a
ã®ã¡ã¢ãªä¸ã®ã¢ãã¬ã¹ãå
±æãããåãã«ãªãã¾ãã
ããã« ref var b
㯠a
ãåç
§ãã¦ãããã a
㨠b
ã¯åãå¤ã§ãããb
ãå¤æ´ãã㨠a
ã®å¤ãæ¸ãæããã
private void TestRef()
{
var a = 1 ;
ref var b = ref PassThrough(ref a);
b = 2 ;
Console.WriteLine(a);
}
private ref int PassThrough(ref int b)
{
ref var c = ref b;
return ref c;
}
ref æ»ãå¤ã¯ C# 7.2 ããå©ç¨å¯è½ã«ãªã£ãã®ã§ 2017 å¹´æ«ããã®æ©è½ã§ããã¾ã ref readonly
ã®ãããªæ»ãå¤ã®æ¸ãæ¹ãã§ãããï¼ããå¾è¿°ã®ããã«ããã©ã¼ãã³ã¹ã®è¦³ç¹ã§ã¯æ³¨æãå¿
è¦ï¼
ãã®ã»ãã«ããåç
§æ¸¡ãã ãã©èªã¿åãå°ç¨ããªã in
ã使ããã®ã§ã大ããæ§é ä½ã渡ãã¨ãã¯ããã©ã¼ãã³ã¹æ¹åã«ã¤ãªããå¼æ°ã®æå®ã«ãªãã
å¾æ¥ã® out
ã¯ãåç
§æ¸¡ãããããã¡ã½ããã®ä¸ã§ãã¡ã½ããå¤ã®å¤æ°ã®å¤ãæ¸ãæãããã¨ãã§ããã®ã«å¯¾ã㦠in
ã¯ãå
¥åç¨ããæ示ãã¾ãã
ã³ã³ãã¤ã© ã®åä½ã¨ãã¦ã¯ in/out 㯠ref ãªã®ã§ãå¼æ°éãã®ãªã¼ãã¼ãã¼ã ã¯ã§ããªãã
è£è¶³ã¨ãã¦ãæ§é ä½ã§ã¯ãªãã¯ã©ã¹ã®å ´åã¯ãã¾ãããã©ã¼ãã³ã¹ã®æ¹åã«å¹æããªããçç±ã¯åç
§åãªã®ã§ãã¤ã³ã¿ã®ãããªåãããããã¼ãé åãå©ç¨ãã¦ããããããã¼ã¿ãã®ãã®ãã³ãã¼ããããã¨ããªãã
ref readonly/in ã®é£ãã
Defensive Copy ãçºçãã¦ãã¾ãã
å¼æ°ã®å ´å㯠in
ã§ãæ»ãå¤ã®å ´å㯠ref readonly
ã¨ãã¦ããã®åé¡ãã©ã¡ãã®å ´åã§ãçºçãã¦ãã¾ããï¼å¾è¿°ã® Generics ã¯å¥ï¼
ããã°ã©ã ã®é½åã¨ãã¦ãå¼ã³åºãå´ã¯ãã¡ã½ããã®å
é¨ã§å¤ãæ¸ãæãã£ã¦ããªããã¨ãä¿è¨¼ããæ¹æ³ãæããªãã®ã§ããããããã¡ã½ãããå¼ãã æç¹ã§ç¡æ¡ä»¶ã«ã³ãã¼ãä½ã£ã¦ãã¾ãåãã®ãã¨ã Defensive Copy ã¨ããã
対çï¼
æ§é ä½ã readonly ã«ãã¦ãã
é¢æ°å
ã§ãã£ã¼ã«ãã®æ¸ãæãããªããã¨ãä¿è¨¼ãã¦ãã
readonly struct ReadOnly
{
public readonly int X;
}
struct Foo
{
..
public readonly int Add() => X + Y;
public int Sub() => X - Y;
..
}
ã³ãã¼æå¶
æ§é ä½ã®æ¡å¼µã¡ã½ãããä½ãã¨ãã¯ãåç
§æ¸¡ãã«ãããGenerics ã«ããã in å¼æ°ã¯ã§ããªãã
ããã¯ã³ã³ãã¤ã© ãåã¯å¤åãåç
§åããå¤æã§ãã¦ããªãã®ã§ãä»æ§ã¨ã㦠in å¼æ°ã«ã§ããªããï¼åç
§åã®ã¨ãã¯åç
§æ¸¡ãã§ããå¿
è¦ããªãï¼
static void Process<T >(in this T data)
{
}
static void Process<T >(ref this T data) : where T : struct
{
}
in ã使ã£ã overload ãããã¨ãããstruct èªä½ã readonly ã«ãã¦ããã
readonly struct Complex
{
public double R { get ; }
public double I { get ; }
public static Complex operator + (in Complex x, in Complex y)
=> new Complex(x.R + y.R, x.I + y.I);
}
ã¨ãããããåºæ¬çã«ã¯ in 㯠readonly 㪠struct ã«ä½¿ããã®ãã¨ããèãæ¹ã«ãªãã¯ãã
ValueTuple
å¿ååã®æ´å²ã¿ãããªãã®ãLINQ ã¨ãã£ãå±æçãªã¨ããã§ä½¿ãã¨ãããã®ãValueTuple ã¯ãå¤ãå¤æ´ã§ããæ§é ä½ã¨ãã¦èãã¦ããã
ã³ã¬ã¯ã·ã§ã³ããã³ã¬ã¯ã·ã§ã³ãé¸æããåä½ãªãããValueTuple ã¯ãã¼ãã使ããªãããããããããã©ã¼ãã³ã¹ä¸ã®ç¸æ§ãããè¨è¨ã ã¨æãã
var q1 = collection.Select(x => (value: x, power: x * x));
var q2 = collection.Select(x => new { Value = x, Power = x * x });
var q3 = collection.Select(x => Tuple.Create(x, x * x));
Span
é£ç¶ããã¡ã¢ãªé åãç´æ¥åç
§ã§ãããunsafe ãããªã managed ãªç¶æ
ã§ã¢ã¯ã»ã¹ã§ãããé
åãæååãããã¡ã¢ãªã®å確ä¿ãããªãé¨åçãªåç
§ãã§ããã
const string text = âab123cdâ;
var span = text.AsSpan(2 , 3 );
var sub = text.Substring(2 , 3 );
ä¸èº«ã read ããã ããªã span ãä¸æãæ´»ç¨ãããã¨ã§ãç¡é§ãªã³ãã¼ãé¿ãã¦é«éåããããã¨ãã§ããã
ã§ããå
é¨çã«ã³ãã¼ãçºçãã¦ãããã©ãããªãã¦ãè¨èªã®ç解ãæ·±ã¾ããªãã¨æé©åã§ããªãã
string.Create
string.Create 㯠Span ã使ã£ã¦ããã®ã§ãç¡é§ãªãªãã¸ã§ã¯ããçæããããã¨ãªãæååãä½æãããã¨ãã§ããã
以ä¸ã¯ byte
åã®å¤ãæååã«å¤æããï¼ä¾ãã°ãæåå "01101100" ã«ããï¼ãã®ã§ buffer ã span ãªã®ã§ StringBuilder ã®ãããªä¸éå¤æ°ãåå¨ããªããã¨ã¦ããã¯ãã«ã«ãªæè¡ã ã¨æã£ãã
static string ToBitString(byte value )
=> string .Create(8 , value , (buffer, state) =>
{
const byte on = 0b_0000_0001 ;
for (var i = 0 ; i < buffer.Length; i++ )
{
buffer[buffer.Length - 1 - i]
= ((state >> i & on ) == on ) ? '1' : '0' ;
}
});
ããã¯ã¹åãåé¿ãã
å¤ãç£å» ã使ã£ã¦ã¯ãããªã
System.Collections
System.Collections.Generics
é generics ã³ã¬ã¯ã·ã§ã³ãªã®ã§ä½¿ããªãã»ãããããåå空é ãåºã¦ããã注æããã»ããããã
å¤ã代å
¥ããã¨ããã¯ã¹åãã¦ãã¾ãã
static void Foo(Enum value )
{}
static void Foo<T >(T value ) where T : struct , Enum
{}
æ§é ä½ã interface åã¨ãã¦æ±ã
æ£ç´ãæ§é ä½ã®é«éåãã¯ããã¯ã¯ããã¢ãã¯ã ã¨æãã
struct 㯠object ãããã¤ã³ãã¨ãã¦ã¤ã³ã¿ã¼ãã§ã¼ã¹ãçµç±ãã㨠Box åãçºçãã¦ãã¾ãããããã㧠generics ã使ãã¨è±ä»®æ³åã«ãªãã
static void Interface(IDisposable x)
=> x.Dispose();
static void NonGeneric(X x)
=> ((IDisposable)x).Dispose();
static void Generic<T >(T x)
where T : IDisposable
=> x.Dispose();
ä¸çªããè¨ããããããªã®ããæ¯è¼ã® equal é¢ä¿ãªã®ã§ããããã£ãã¨ãã㯠record ã使ããã¨ã§ãåé¿ã§ããã¨æãã¾ãã
ç¥ããªãéã«ä½ãããã¤ã³ã¹ã¿ã³ã¹ ã«æ°ãé
ã
å¤æ°ã®ãã£ããã£ã¼ãï¼ãé ãã¯ã©ã¹ã®çæã¨ãããã¨ã«ãªãã¾ãããªã®ã§ããã¼ã確ä¿ã¨å©ä¾¿æ§ã¯ãã¬ã¼ããªã ã®é¢ä¿ã§ãã
å
·ä½çã«ã¯ãã©ã ãå¼ ãå¿åã¡ã½ããå
ã§å¤é¨ã¹ã³ã¼ãã®å¤æ°ãåç
§ããã¨ããå¤æ°ãã¯ãã¼ã¸ã£ ã«ãã£ããã£ããããã¨ãæãã¦ãã¾ãããã®ãã¯ãã¼ã¸ã£ ãã¯ãã¼ãä¸ã«ãªãã¸ã§ã¯ãã¨ãã¦çæããããã¨ã«ãªãã¾ãã
以ä¸ã¯ id ããã£ããã£ãããä¾ã§ããVisual Studio ã§ã¯ "=>" ã®é¨åã«ã«ã¼ã½ã«ãåãããã¨ããã£ããã£ããã¦ãããã©ããããç¥ããã¨ãã§ãã¾ãã
static async Task<Person> GetAsync(int id)
{
var people = await QueryFromDbAsync();
return people.FirstOrDefault(x => x.Id == id);
}
ãªã®ã§ããã£ã«ã¿ãªã³ã°é¨åæ¡ä»¶ãã©ã ãå¼ ã®å¤ã«ç½®ããæ¡å¼µã¡ã½ããã«ãã¦èªä½ãããããããã¨ã«ãªãã
static async Task<Person> GetAsync(int id)
{
var people = await QueryFromDbAsync();
foreach (var person in people)
{
if (person.Id == id) return person;
}
return null ;
}
public static T ? FirstOrDefault<T , TState>(
this IEnumerable<T > source, TState state, Func<T , TState, bool > predicate)
{
foreach (var x in source)
{
if (predicate(x, state))
return x;
}
return default ;
}
ã¾ããã©ã ãå¼ ãå¿åã¡ã½ããã¯å¤ã®å¤æ°ããã£ããã£ã§ãã¦ãã¾ããããå¤æ°åã¨ã㦠x ã y ã i ã使ã£ãã¤ããããå¤ã®å¤æ°ããã£ããã£ãã¦ãã¾ã£ã¦ãã°ã«ãªããã¨ãããã¾ããããããã¨ãã¯ãéçã©ã ãå¼ ã使ããã¨ã§ãå¤é¨ã¹ã³ã¼ãã®å¤æ°ãå
¥ãè¾¼ã¾ãªãããã«ï¼ãã種ï¼æ示ãããã¨ã«ãªãã¾ãã
var x = 10 ;
var result
= Enumerable.Range(0 , 10 )
.Where(static x => x % 2 is 0 )
.ToDictionary(static x => x, static y => x * x);
æéã¨ãªã½ã¼ã¹ãæå¹ã«ä½¿ã
éåæ IO ã使ã
await ãã¦ããéã«ã§ãããã¨ãããã
var url = "...." ;
var client = new HttpClient();
var rss = await client.GetStringAsync(url);
var node = XElement.Parse(rss);
並åå¦ç
ããããã®å¦çãç¬ç«ãã¦ãããªããParallel ã«ããã¨å¦çæéãç縮ã§ããããã
var t1 = LoadFile1Async();
var t2 = LoadFile2Async();
var t3 = LoadFile3Async();
await Task.WhenAll(t1, t2, t3);
ãã£ãã·ã³ã°
ã¾ãèãæ¹ã¨ã㦠Enum .GetValues ã¯ãªãã¬ã¯ã·ã§ã³ãå
é¨çã«å©ç¨ãã¦ãããããæ¯è¼çã³ã¹ãã大ããæä½ã«ãªã£ã¦ãã¾ãã
ãªã®ã§ããã®å¦çãç¹°ãè¿ãå®è¡ãããã¨ã¯é¿ããããããã§ããã£ãã·ã³ã°ãå©ç¨ãããã¨ã§ãä¸åº¦ã ãå¤ãåå¾ãã¦ã以éã¯ä¿åãããå¤ã使ããã¨ã§ããã©ã¼ãã³ã¹ãä¸ããã
public static class FastEnum
{
public static IReadOnlyList<T > GetValues<T >()
where T : struct , Enum
=> Cache<T >.Values;
private static class Cache<T>
where T : struct , Enum
{
public static readonly T [] Values;
static Cache()
=> Values = (T [])Enum.GetValues(typeof (T) );
}
}
ãã ãããã£ãã·ã¥ãããµã¤ãºã大ãããªãã¨ã¡ã¢ãªæ¶è²»ã大ãããªãããã£ãã·ã¥ãããå¤ãå¤æ´ãããå ´åãããã¨ããã£ãã·ã¥ã®ç¡å¹åãæ´æ°ãå¿
è¦ã«ãªãã®ã§ãããªãã
ã³ã¬ã¯ã·ã§ã³ã®ãã¼ã¿ã Add/Remove/Clear ãªã©ã®æä½ãããã«ã大éã®ãã¼ã¿ã«ã¢ã¯ã»ã¹ããå ´é¢ã§ã¯ Span ãæå¹ãªãã¨ãããããªã¹ããå¤æ´ããªããã¨ã¯éè¦ã
List<int > list = [0 , 1 , 2 , 3 , 4 ];
var span = CollectionsMarshal.AsSpan(list);
foreach (var x in span)
{
}
Frozen Collections
Frozen Collection ã¯ã³ã¬ã¯ã·ã§ã³ãä½æããå¾ã¯å¤æ´ãã§ãã¾ãããã¹ã¬ããã»ã¼ãã§ãã«ãã¹ã¬ããç°å¢ã§å®å
¨ã«å©ç¨ã§ããã®ãç¹å¾´ã
ãã¼ã¿ãåºå®åããããã¨ã§ãæ¤ç´¢ãæé©åããã¦ãã¾ããContains ãªã©ãé«éåã
åç´ãªãã¨ãªã®ã§ãFrozen ã§ãããã¨ãè¦ãã¦ããã° OK ã ã¨æãã¾ãã
var data = new Dictionary<int , string >
{
{ 1 , "One" },
{ 2 , "Two" },
{ 3 , "Three" },
};
var frozenData = data.ToFrozenDictionary();
æ§é ä½ã¯ yield return ããªã
ãããããããæ§é ä½ãå©ç¨ãããã¨ã§ãã¼ãã¢ãã±ã¼ã·ã§ã³ ãåé¿ãããã¯ããã¯ã ã¨æãã¾ããå¤åãªã®ã§ããã£ãã·ã¥å¹çãæãã£ã¦ãé »ç¹ãªã¤ãã¬ã¼ã·ã§ã³ é¨åã§æ§è½ãåä¸ããããã¯ããã¯ã®ã¯ãã§ãã
foreach ã LINQ 㯠GetEnumerator ã使ã£ã¦ã¤ãã¬ã¼ã·ã§ã³ ãéå§ããã®ã§ãæ§é ä½ãè¿ãããã¨ãã¯ãããã¾ã§ã®ä¾ã®ããã«ã¤ã³ã¿ã¼ãã§ã¼ã¹å IEnumerator<T>
ã¨ãã¦æ±ãããã¨ãæé»çã«ãã¯ã·ã³ã°ãçºçããå¹çã®æªããããã
yield return ã¯ç¶æ
ãã·ã³ãªã®ã§è¨ããã¨ããã¨ããã¯åãã¯ãã
class Program
{
static void Main()
{
var range = new RangeEnumerable(1 , 10 );
foreach (var num in range)
{
Console.WriteLine(num);
}
}
}
public struct RangeEnumerable : IEnumerable<int >
{
private readonly int _start;
private readonly int _end;
public RangeEnumerable(int start, int end)
{
_start = start;
_end = end;
}
public Enumerator GetEnumerator() => new Enumerator(_start, _end);
IEnumerator<int > IEnumerable<int >.GetEnumerator() => GetEnumerator();
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public struct Enumerator : IEnumerator<int >
{
private readonly int _end;
private int _current;
public Enumerator(int start, int end)
{
_current = start - 1 ;
_end = end;
}
public int Current => _current;
object IEnumerator.Current => Current;
public bool MoveNext()
{
if (_current < _end)
{
_current++ ;
return true ;
}
return false ;
}
public void Reset() => throw new NotSupportedException();
public void Dispose(){}
}
}
è£è¶³ï¼C# ã®ã³ã³ãã¤ã© ã¯ãç¹å®ã®ã¤ã³ã¿ã¼ãã§ã¼ã¹åãç´æ¥æå®ããªãã¦ãã対å¿ããã¡ã½ãããããããã£ãåå¨ãã¦ããã°ãã³ã¼ããæ£ããåä½ããã¾ããããã¯åãå³å¯ã«ã¤ã³ã¿ã¼ãã§ã¼ã¹ãå®è£
ãã¦ããå¿
è¦ãç¡ãã¨ããç¹ã§ "duck typing " ã¨å¼ã°ãããã®ã§ãã
åè