C# と VB.NET の質問掲示板

ASP.NET、C++/CLI、Java 何でもどうぞ

C# と VB.NET の入門サイト

Re[3]: Tupleのforeachでの分解


(過去ログ 176 を表示中)

[トピック内 8 記事 (1 - 8 表示)]  << 0 >>

■101137 / inTopicNo.1)  Tupleのforeachでの分解
  
□投稿者/ B.B (8回)-(2023/01/09(Mon) 10:44:56)

分類:[C#] 

Visual Studio Community 2022
windows10 pro

KeyValuePairを使った以下のコードでは動作します
【コード】
var list = new List<KeyValuePair<string, int>> {
    new KeyValuePair<string, int>("リンゴ", 7),
    new KeyValuePair<string, int>("みかん", 2),
};
foreach (var (name, count) in list)
{
    MessageBox.Show($"{name} : {count}");
}

Tupleを使った以下のコードではエラーになります
【コード】
var list = new List<Tuple<string, int>> {
    new Tuple<string, int>("リンゴ", 7),
    new Tuple<string, int>("みかん", 2),
};
foreach (var (name, count) in list)
{
    MessageBox.Show($"{name} : {count}");
}

分解せずに受けるとitem1、item2になり不便です。name, countと名前を付けたいのです
Tupleを使った場合どのようにすれば意図した動作になるでしょうか
よろしくお願いします

引用返信 編集キー/
■101138 / inTopicNo.2)  Re[1]: Tupleのforeachでの分解
□投稿者/ Hongliang (1263回)-(2023/01/09(Mon) 11:31:21)
.NET Frameworkでも4.7の時点でDeconstructが提供されていて、普通に分解できますが…。
.NETのバージョンは何でしょうか?
https://learn.microsoft.com/ja-jp/dotnet/api/system.tupleextensions?view=net-7.0
引用返信 編集キー/
■101139 / inTopicNo.3)  Re[2]: Tupleのforeachでの分解
□投稿者/ Hongliang (1264回)-(2023/01/09(Mon) 11:33:20)
なおDeconstructは自分で実装することもできます。
https://ufcpp.net/study/csharp/datatype/deconstruction/
引用返信 編集キー/
■101140 / inTopicNo.4)  Re[1]: Tupleのforeachでの分解
□投稿者/ 魔界の仮面弁士 (3528回)-(2023/01/09(Mon) 11:49:28)
No101137 (B.B さん) に返信
> Visual Studio Community 2022
> windows10 pro

デコンストラクタの話ですよね。
大事なところですが、『ターゲット フレームワーク』は何にしていますか?


KeyValuePair<TKey,TValue> の Deconstruct メソッドは、
.NET Standard 2.1 以降 / .NET Core 2.0 以降で
KeyValuePair<TKey,TValue> 自身のインスタンス メソッドとして実装されています。
https://learn.microsoft.com/ja-jp/dotnet/api/system.collections.generic.keyvaluepair-2.deconstruct?view=net-7.0

.NET Framework の KeyValuePair にはデコンストラクタが標準実装されていないので、
拡張メソッドで用意する必要があります。


Tuple<T1,T2> の Deconstruct メソッドは、
.NET Standard 2.0 以降 / .NET Framework 4.7/4.7.1/4.7.2/4.8/4.8.1 において、
拡張メソッドとして System.TupleExtensions クラスで実装されています。
https://learn.microsoft.com/ja-jp/dotnet/api/system.tupleextensions.deconstruct?view=net-7.0#system-tupleextensions-deconstruct-2%28system-tuple%28%28-0-1%29%29-0@-1@%29

.NET Standard 2.0 には .NET Framework 4.6.1/4.6.2 が含まれますが、
System.TupleExtensions は .NET Framework 4.7 以降で追加されたものなので、
それ以前のバージョンでは使えません。


> Tupleを使った場合どのようにすれば意図した動作になるでしょうか
デコンストラクタを拡張メソッドで補ってやれば、.NET Framework 4 でも分解できます。
自作する代わりに、同等のアセンブリを参照設定なり Nuget しても良いですけれども。

static class ExampleExtensions
{
  public static void Deconstruct<T, U>(this KeyValuePair<T, U> pair, out T key, out U value)
  {
    key = pair.Key;
    value = pair.Value;
  }

  public static void Deconstruct<T1, T2>(this Tuple<T1, T2> x, out T1 item1, out T2 item2)
  {
    item1 = x.Item1;
    item2 = x.Item2;
  }
}


極端な話、Tuple クラスも自作してやれば、.NET Framework 3.5 であっても動きます。

public class Tuple<T1,T2>
{
  public T1 Item1;
  public T2 Item2;
  public Tuple(T1 item1, T2 item2)
  {
    Item1 = item1;
    Item2 = item2;
  }
}


拡張メソッド用の属性も用意すれば、 .NET Framework 2.0/3.5 であっても動きます。
コンパイラ側のバージョンにもよりますけれどね。

namespace System.Runtime.CompilerServices
{
class ExtensionAttribute : global::System.Attribute { }
}

引用返信 編集キー/
■101147 / inTopicNo.5)  Re[2]: Tupleのforeachでの分解
□投稿者/ B.B (9回)-(2023/01/10(Tue) 05:17:22)
No101138 (Hongliang さん) に返信
> .NET Frameworkでも4.7の時点でDeconstructが提供されていて、普通に分解できますが…。
> .NETのバージョンは何でしょうか?

.NET Framework 4.8です。新規でプロジェクトを作成すると普通に分解できました…


No101140 (魔界の仮面弁士 さん) に返信
> デコンストラクタの話ですよね。
> 大事なところですが、『ターゲット フレームワーク』は何にしていますか?

Visual Studio 2017で作成したプロジェクトを2022で開いて追加でプログラミングしているのが原因だったようです。
ターゲット フレームワークなどは最新で構わないのでその辺を調べてみます

Hongliangさん、魔界の仮面弁士さん、ありがとうございました。.NET Frameworkに関して無知ゆえにお騒がせいたしました。


解決済み
引用返信 編集キー/
■101148 / inTopicNo.6)  Re[3]: Tupleのforeachでの分解
□投稿者/ 魔界の仮面弁士 (3533回)-(2023/01/10(Tue) 08:00:49)
No101147 (B.B さん) に返信
> Visual Studio 2017で作成したプロジェクトを2022で開いて追加でプログラミングしているのが原因だったようです。
> ターゲット フレームワークなどは最新で構わないのでその辺を調べてみます

うーん。何か追加で NuGet されていたりしましたか?

VS2017 製のソースを VS20022 で開くという組み合わせは未検証なのですが、
TupleExtensions の名前空間は System ですし、要求されるアセンブリも mscorlib.dll なので、
ターゲット フレームワークが「.NET Framework 4.7 以上」にさえなっているのなら、
VS2017 で作成した時代のプロジェクトでも分解できて良さそうなものなのですけれどね。


>>>> KeyValuePairを使った以下のコードでは動作します
>>>> Tupleを使った以下のコードではエラーになります

ちなみに System.ValueTuple<T1,T2> 構造体の分解に関しても .NET Framework 4.7 以降が対象です。

var list1 = new List<ValueTuple<string, int>> { ("リンゴ", 7), ("みかん", 2) };
foreach (var (name, count) in list1)
{
  Console.WriteLine(name + " : " + count);
}


ただし、NuGet で Microsoft 公式の『System.ValueTuple』を追加すれば、
上記を .NET Framework 4.5 〜 4.6.2 でも実行可能となります。分解もできます。
https://www.nuget.org/packages/System.ValueTuple


上記と似た名前で、.NET Framework 2.0 以降を対象とした『System.Tuples』というライブラリもありますが、
こちらは分解に対応していない、異なるタプルクラスです。名前空間も異なります(System.Tuples.Tuple<T1, T2> クラス)。
https://www.nuget.org/packages/System.Tuples/

Microsoft のものではなく、 Adis Hamzic'氏の作ったものではありますが(もともとは codeplex での公開)、
No101140 と同様、拡張メソッドで補ってやることで分解構文の利用が可能になります。

//
public static void Deconstruct<T1, T2>(this System.Tuples.Tuple<T1, T2> x, out T1 item1, out T2 item2)
{
  item1 = x.Element1;
  item2 = x.Element2;
}
解決済み
引用返信 編集キー/
■101152 / inTopicNo.7)  Re[4]: Tupleのforeachでの分解
□投稿者/ B.B (10回)-(2023/01/12(Thu) 16:27:32)
2023/01/12(Thu) 18:03:37 編集(投稿者)

No101148 (魔界の仮面弁士 さん) に返信
> ■No101147 (B.B さん) に返信

> うーん。何か追加で NuGet されていたりしましたか?

ズバリそれでした、重ね重ねありがとうございました。
以下のものをインストールしていました
System.ValueTuple 4.5.0 (作成者 Microsoft)

削除したら問題なく動作するようになりました。Visual Studio上でも警告が出てました。
ほんとにお騒がせしました、エスパーのような回答で素晴らしいです

引用返信 編集キー/
■101153 / inTopicNo.8)  Re[3]: Tupleのforeachでの分解
□投稿者/ B.B (11回)-(2023/01/12(Thu) 18:01:52)
警告のコピー

一部の NuGet パッケージが現在のターゲット フレームワークとは異なるターゲット フレームワークを使用してインストールされていて、再インストールが必要になる可能性があります。詳細については、https://docs.nuget.org/docs/workflows/reinstalling-packages を参照してください。



引用返信 編集キー/


トピック内ページ移動 / << 0 >>

このトピックに書きこむ

過去ログには書き込み不可

管理者用

- Child Tree -