はじめに:
判別共用体は、タグ付き共用体または素体共用体とも呼ばれ、単一の変数にさまざまなタイプのデータを格納できるようにするプログラミング構造。これらは、限られた数のバリアントで値のセットを表すタイプセーフな方法を提供します。
問題の理解:
この質問は、C# の Union クラスを提案しています。 C スタイルのユニオンと同様の機能を提供します。ただし、このクラスには、Is 関数と As 関数を使用するときにコンパイラによって強制される型チェックがありません。この問題は、ユニオンに実際にその型が含まれていることを確認せずに、特定の型の値を取得しようとしたときに発生します。
C# でタイプセーフなユニオンを実現できますか?
はい、C# では汎用制約とパターン マッチングを使用して、タイプ セーフな判別共用体を実装できます。以下に例を示します:
public abstract class Union<A, B, C> { public abstract T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h); } public class Case1<A, B, C> : Union<A, B, C> { public readonly A Item; public Case1(A item) { Item = item; } public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h) => f(Item); } public class Case2<A, B, C> : Union<A, B, C> { public readonly B Item; public Case2(B item) { Item = item; } public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h) => g(Item); } public class Case3<A, B, C> : Union<A, B, C> { public readonly C Item; public Case3(C item) { Item = item; } public override T Match<T>(Func<A, T> f, Func<B, T> g, Func<C, T> h) => h(Item); }
使用法:
この Union タイプを使用するには、特定のケースのインスタンスを作成します:
var union1 = new Case1<int, string, bool>(5); var union2 = new Case2<int, string, bool>('a'); var union3 = new Case3<int, string, bool>(true);
パターンマッチング:
値を取得するにはユニオンから、パターン マッチングを使用します:
var value1 = union1.Match(n => n, _ => null, _ => null); // Returns 5 (int) var value2 = union2.Match(_ => null, c => c.ToString(), _ => null); // Returns "a" (string) var value3 = union3.Match(_ => null, _ => null, b => b.ToString()); // Returns "True" (string)
結論:
このソリューションは、ジェネリックスとパターン マッチングを利用することにより、C# でタイプセーフな判別ユニオンを提供します。これにより、コードが不正な値にアクセスしようとすることがなくなり、アプリケーションの安全性と正確性が強化されます。
以上がC# でタイプセーフな判別ユニオンを実現するにはどうすればよいでしょうか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。