Tupleクラスを使用する方法はありますが、その中にアイテムの名前を指定しますか?
例えば:
public Tuple<int, int, int int> GetOrderRelatedIds()
これは、OrderGroupId、OrderTypeId、OrderSubTypeId、およびOrderRequirementIdのIDを返します。
私のメソッドのユーザーにどちらがどれであるかを知らせるといいでしょう。 (メソッドを呼び出すと、結果はresult.Item1、result.Item2、result.Item3、result.Item4になります。どちらがどれかは明確ではありません。)
(これらのIdをすべて保持するクラスを作成できることはわかっていますが、これらのIdには既に独自のクラスがあり、この1つのメソッドの戻り値のクラスを作成するのはばかげているようです)
C#7.0(Visual Studio 2017)には、それを行うための新しい構造があります。
(string first, string middle, string last) LookupName(long id)
C#7.0までは、独自の型を定義する以外にこれを行う方法はありませんでした。
これはあなたが尋ねているものの非常に複雑なバージョンです:
class MyTuple : Tuple<int, int>
{
public MyTuple(int one, int two)
:base(one, two)
{
}
public int OrderGroupId { get{ return this.Item1; } }
public int OrderTypeId { get{ return this.Item2; } }
}
なぜクラスを作らないのですか?
.net 4では、おそらく ExpandoObject
を見ることができますが、この単純なケースには使用しないでください。コンパイル時エラーが実行時エラーになるからです。
class Program
{
static void Main(string[] args)
{
dynamic employee, manager;
employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
manager = new ExpandoObject();
manager.Name = "Allison Brown";
manager.Age = 42;
manager.TeamSize = 10;
WritePerson(manager);
WritePerson(employee);
}
private static void WritePerson(dynamic person)
{
Console.WriteLine("{0} is {1} years old.",
person.Name, person.Age);
// The following statement causes an exception
// if you pass the employee object.
// Console.WriteLine("Manages {0} people", person.TeamSize);
}
}
// This code example produces the following output:
// John Smith is 33 years old.
// Allison Brown is 42 years old.
言及する価値のあるものは、メソッド内で 匿名型 ですが、返す場合はクラスを作成する必要がありますそれ。
var MyStuff = new
{
PropertyName1 = 10,
PropertyName2 = "string data",
PropertyName3 = new ComplexType()
};
this postから私の回答を再現します。
C#v7.0以降では、以前はデフォルトでItem1
、Item2
などの名前にデフォルト設定されていたTupleプロパティに名前を付けることができます。
タプルリテラルのプロパティの命名:
var myDetails = (MyName: "RBT_Yoga", MyAge: 22, MyFavoriteFood: "Dosa");
Console.WriteLine($"Name - {myDetails.MyName}, Age - {myDetails.MyAge}, Passion - {myDetails.MyFavoriteFood}");
コンソールの出力:
名前-RBT_Yoga、年齢-22、情熱-Dosa
メソッドからタプル(名前付きプロパティを持っている)を返す:
static void Main(string[] args)
{
var empInfo = GetEmpInfo();
Console.WriteLine($"Employee Details: {empInfo.firstName}, {empInfo.lastName}, {empInfo.computerName}, {empInfo.Salary}");
}
static (string firstName, string lastName, string computerName, int Salary) GetEmpInfo()
{
//This is hardcoded just for the demonstration. Ideally this data might be coming from some DB or web service call
return ("Rasik", "Bihari", "Rasik-PC", 1000);
}
コンソールの出力:
従業員の詳細:Rasik、Bihari、Rasik-PC、1000
名前付きプロパティを持つタプルのリストの作成
var tupleList = new List<(int Index, string Name)>
{
(1, "cow"),
(5, "chickens"),
(1, "airplane")
};
foreach (var Tuple in tupleList)
Console.WriteLine($"{Tuple.Index} - {Tuple.Name}");
コンソールでの出力:
1-牛5-鶏1-飛行機
すべてをカバーしたことを願っています。念のため、私が見逃したものがあれば、コメントでフィードバックをお願いします。
注:私のコードスニペットは、詳細な here としてC#v7の文字列補間機能を使用しています。
アイテムのタイプがすべて異なる場合、より直感的にそれらを取得するために作成したクラスを次に示します。
このクラスの使用法:
var t = TypedTuple.Create("hello", 1, new MyClass());
var s = t.Get<string>();
var i = t.Get<int>();
var c = t.Get<MyClass>();
ソースコード:
public static class TypedTuple
{
public static TypedTuple<T1> Create<T1>(T1 t1)
{
return new TypedTuple<T1>(t1);
}
public static TypedTuple<T1, T2> Create<T1, T2>(T1 t1, T2 t2)
{
return new TypedTuple<T1, T2>(t1, t2);
}
public static TypedTuple<T1, T2, T3> Create<T1, T2, T3>(T1 t1, T2 t2, T3 t3)
{
return new TypedTuple<T1, T2, T3>(t1, t2, t3);
}
public static TypedTuple<T1, T2, T3, T4> Create<T1, T2, T3, T4>(T1 t1, T2 t2, T3 t3, T4 t4)
{
return new TypedTuple<T1, T2, T3, T4>(t1, t2, t3, t4);
}
public static TypedTuple<T1, T2, T3, T4, T5> Create<T1, T2, T3, T4, T5>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5)
{
return new TypedTuple<T1, T2, T3, T4, T5>(t1, t2, t3, t4, t5);
}
public static TypedTuple<T1, T2, T3, T4, T5, T6> Create<T1, T2, T3, T4, T5, T6>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6)
{
return new TypedTuple<T1, T2, T3, T4, T5, T6>(t1, t2, t3, t4, t5, t6);
}
public static TypedTuple<T1, T2, T3, T4, T5, T6, T7> Create<T1, T2, T3, T4, T5, T6, T7>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7)
{
return new TypedTuple<T1, T2, T3, T4, T5, T6, T7>(t1, t2, t3, t4, t5, t6, t7);
}
public static TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> Create<T1, T2, T3, T4, T5, T6, T7, T8>(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8)
{
return new TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8>(t1, t2, t3, t4, t5, t6, t7, t8);
}
}
public class TypedTuple<T>
{
protected Dictionary<Type, object> items = new Dictionary<Type, object>();
public TypedTuple(T item1)
{
Item1 = item1;
}
public TSource Get<TSource>()
{
object value;
if (this.items.TryGetValue(typeof(TSource), out value))
{
return (TSource)value;
}
else
return default(TSource);
}
private T item1;
public T Item1 { get { return this.item1; } set { this.item1 = value; this.items[typeof(T)] = value; } }
}
public class TypedTuple<T1, T2> : TypedTuple<T1>
{
public TypedTuple(T1 item1, T2 item2)
: base(item1)
{
Item2 = item2;
}
private T2 item2;
public T2 Item2 { get { return this.item2; } set { this.item2 = value; this.items[typeof(T2)] = value; } }
}
public class TypedTuple<T1, T2, T3> : TypedTuple<T1, T2>
{
public TypedTuple(T1 item1, T2 item2, T3 item3)
: base(item1, item2)
{
Item3 = item3;
}
private T3 item3;
public T3 Item3 { get { return this.item3; } set { this.item3 = value; this.items[typeof(T3)] = value; } }
}
public class TypedTuple<T1, T2, T3, T4> : TypedTuple<T1, T2, T3>
{
public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4)
: base(item1, item2, item3)
{
Item4 = item4;
}
private T4 item4;
public T4 Item4 { get { return this.item4; } set { this.item4 = value; this.items[typeof(T4)] = value; } }
}
public class TypedTuple<T1, T2, T3, T4, T5> : TypedTuple<T1, T2, T3, T4>
{
public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
: base(item1, item2, item3, item4)
{
Item5 = item5;
}
private T5 item5;
public T5 Item5 { get { return this.item5; } set { this.item5 = value; this.items[typeof(T5)] = value; } }
}
public class TypedTuple<T1, T2, T3, T4, T5, T6> : TypedTuple<T1, T2, T3, T4, T5>
{
public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
: base(item1, item2, item3, item4, item5)
{
Item6 = item6;
}
private T6 item6;
public T6 Item6 { get { return this.item6; } set { this.item6 = value; this.items[typeof(T6)] = value; } }
}
public class TypedTuple<T1, T2, T3, T4, T5, T6, T7> : TypedTuple<T1, T2, T3, T4, T5, T6>
{
public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7)
: base(item1, item2, item3, item4, item5, item6)
{
Item7 = item7;
}
private T7 item7;
public T7 Item7 { get { return this.item7; } set { this.item7 = value; this.items[typeof(T7)] = value; } }
}
public class TypedTuple<T1, T2, T3, T4, T5, T6, T7, T8> : TypedTuple<T1, T2, T3, T4, T5, T6, T7>
{
public TypedTuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6, T7 item7, T8 item8)
: base(item1, item2, item3, item4, item5, item6, item7)
{
Item8 = item8;
}
private T8 item8;
public T8 Item8 { get { return this.item8; } set { this.item8 = value; this.items[typeof(T8)] = value; } }
}
MichaelMocko Answeredは素晴らしいです。
しかし、私は私が把握しなければならなかったいくつかのことを追加したい
(string first, string middle, string last) LookupName(long id)
上記の行は、コンパイル時間エラーを使用している場合、。net framework <4.7
したがって、。net framework <4.7を使用しているプロジェクトがあり、それでもWorkAroundがインストールされるよりもValueTupleを使用したい場合thisnugetパッケージ
いいえ、タプルメンバーに名前を付けることはできません。
中間には、Tupleの代わりに ExpandoObject を使用します。
これは非常に面倒であり、C#の将来のバージョンでこのニーズに対応できると期待しています。別のデータ構造タイプを使用するか、コードを読んでいる他の人の健全性のために、「アイテム」の名前を変更するのが最も簡単な回避策です。
Tuple<ApiResource, JSendResponseStatus> result = await SendApiRequest();
ApiResource apiResource = result.Item1;
JSendResponseStatus jSendStatus = result.Item2;
クラスを作成すると思いますが、別の選択肢は出力パラメーターです。
public void GetOrderRelatedIds(out int OrderGroupId, out int OrderTypeId, out int OrderSubTypeId, out int OrderRequirementId)
タプルには整数しか含まれていないため、Dictionary<string,int>
で表すことができます
var orderIds = new Dictionary<string, int> {
{"OrderGroupId", 1},
{"OrderTypeId", 2},
{"OrderSubTypeId", 3},
{"OrderRequirementId", 4}.
};
しかし、私はそれもお勧めしません。
私はアイテム名をsummayに書きます。したがって、関数helloworld()の上にマウスを移動すると、テキストはhello = Item1およびworld = Item2と表示されます。
helloworld("Hi1,Hi2");
/// <summary>
/// Return hello = Item1 and world Item2
/// </summary>
/// <param name="input">string to split</param>
/// <returns></returns>
private static Tuple<bool, bool> helloworld(string input)
{
bool hello = false;
bool world = false;
foreach (var hw in input.Split(','))
{
switch (hw)
{
case "Hi1":
hello= true;
break;
case "Hi2":
world= true;
break;
}
}
return new Tuple<bool, bool>(hello, world);
}
なぜ誰もが人生をそんなに大変にしているのか。タプルはむしろ一時データ処理用です。常にタプルを操作すると、ある時点でコードが非常に理解しにくくなります。 すべてのクラスを作成すると、プロジェクトが肥大化する可能性があります。
しかし、それはバランスについてです...
あなたの問題は、あなたがクラスを望んでいるもののようです。また、完全を期すために、このクラスにはコンストラクタも含まれています。
これは適切なパターンです
public class OrderRelatedIds
{
public int OrderGroupId { get; set; }
public int OrderTypeId { get; set; }
public int OrderSubTypeId { get; set; }
public int OrderRequirementId { get; set; }
public OrderRelatedIds()
{
}
public OrderRelatedIds(int orderGroupId)
: this()
{
OrderGroupId = orderGroupId;
}
public OrderRelatedIds(int orderGroupId, int orderTypeId)
: this(orderGroupId)
{
OrderTypeId = orderTypeId;
}
public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId)
: this(orderGroupId, orderTypeId)
{
OrderSubTypeId = orderSubTypeId;
}
public OrderRelatedIds(int orderGroupId, int orderTypeId, int orderSubTypeId, int orderRequirementId)
: this(orderGroupId, orderTypeId, orderSubTypeId)
{
OrderRequirementId = orderRequirementId;
}
}
または、本当にシンプルにしたい場合:型初期化子を使用することもできます:
OrderRelatedIds orders = new OrderRelatedIds
{
OrderGroupId = 1,
OrderTypeId = 2,
OrderSubTypeId = 3,
OrderRequirementId = 4
};
public class OrderRelatedIds
{
public int OrderGroupId;
public int OrderTypeId;
public int OrderSubTypeId;
public int OrderRequirementId;
}