ฉันเคยเห็น Tuple ที่เปิดตัวใน. Net 4 แต่ฉันนึกไม่ออกว่าจะใช้งานได้ที่ไหน เราสามารถสร้างคลาสหรือโครงสร้างแบบกำหนดเองได้เสมอ
ฉันเคยเห็น Tuple ที่เปิดตัวใน. Net 4 แต่ฉันนึกไม่ออกว่าจะใช้งานได้ที่ไหน เราสามารถสร้างคลาสหรือโครงสร้างแบบกำหนดเองได้เสมอ
คำตอบ:
นั่นคือประเด็น - สะดวกกว่าที่จะไม่สร้างคลาสหรือโครงสร้างแบบกำหนดเองตลอดเวลา เป็นการปรับปรุงเช่นAction
หรือFunc
... คุณสามารถสร้างประเภทนี้ได้ด้วยตัวเอง แต่สะดวกที่มีอยู่ในกรอบ
convenient not to make a custom class
ทำในสิ่งที่คุณหมายถึงโดย คุณหมายถึงการสร้างอินสแตนซ์คลาสที่กำหนดเองโดยใช้=new..()
?
ด้วย tuples คุณสามารถใช้พจนานุกรมสองมิติ (หรือ n มิติสำหรับเรื่องนั้น) ได้อย่างง่ายดาย ตัวอย่างเช่นคุณสามารถใช้พจนานุกรมดังกล่าวเพื่อใช้การแมปการแลกเปลี่ยนสกุลเงิน:
var forex = new Dictionary<Tuple<string, string>, decimal>();
forex.Add(Tuple.Create("USD", "EUR"), 0.74850m); // 1 USD = 0.74850 EUR
forex.Add(Tuple.Create("USD", "GBP"), 0.64128m);
forex.Add(Tuple.Create("EUR", "USD"), 1.33635m);
forex.Add(Tuple.Create("EUR", "GBP"), 0.85677m);
forex.Add(Tuple.Create("GBP", "USD"), 1.55938m);
forex.Add(Tuple.Create("GBP", "EUR"), 1.16717m);
forex.Add(Tuple.Create("USD", "USD"), 1.00000m);
forex.Add(Tuple.Create("EUR", "EUR"), 1.00000m);
forex.Add(Tuple.Create("GBP", "GBP"), 1.00000m);
decimal result;
result = 35.0m * forex[Tuple.Create("USD", "EUR")]; // USD 35.00 = EUR 26.20
result = 35.0m * forex[Tuple.Create("EUR", "GBP")]; // EUR 35.00 = GBP 29.99
result = 35.0m * forex[Tuple.Create("GBP", "USD")]; // GBP 35.00 = USD 54.58
มีบทความที่ยอดเยี่ยมในนิตยสาร MSDN ที่พูดถึงข้อควรพิจารณาเกี่ยวกับการปวดท้องและการออกแบบที่เพิ่ม Tuple ลงใน BCL การเลือกระหว่างประเภทค่าและประเภทอ้างอิงเป็นสิ่งที่น่าสนใจอย่างยิ่ง
ตามที่บทความนี้มีความชัดเจนแรงผลักดันที่อยู่เบื้องหลัง Tuple คือกลุ่มต่างๆมากมายใน Microsoft ที่ใช้งานได้ทีม F # อยู่ข้างหน้า แม้ว่าจะไม่ได้กล่าวถึง แต่ฉันคิดว่าคีย์เวิร์ด "ไดนามิก" ใหม่ใน C # (และ VB.NET) ก็มีส่วนเกี่ยวข้องเช่นกันสิ่งที่เป็นสิ่งที่พบบ่อยมากในภาษาไดนามิก
เป็นอย่างอื่นโดยเฉพาะอย่างยิ่งไม่ได้ดีไปกว่าการสร้าง poco ของคุณเองอย่างน้อยคุณก็สามารถให้ชื่อที่ดีกว่าแก่สมาชิกได้
UPDATE: เนื่องจากการแก้ไขครั้งใหญ่ใน C # เวอร์ชัน 7 ตอนนี้ได้รับความรักทางไวยากรณ์มากขึ้น ประกาศเบื้องต้นในบล็อกโพสต์นี้
นี่คือตัวอย่างเล็ก ๆ - สมมติว่าคุณมีวิธีการที่ต้องค้นหาหมายเลขอ้างอิงและที่อยู่อีเมลของผู้ใช้โดยระบุรหัสผู้ใช้ คุณสามารถสร้างคลาสแบบกำหนดเองที่มีข้อมูลนั้นได้ตลอดเวลาหรือใช้พารามิเตอร์ ref / out สำหรับข้อมูลนั้นหรือคุณสามารถส่งคืนทูเพิลและมีลายเซ็นวิธีการที่ดีโดยไม่ต้องสร้าง POCO ใหม่
public static void Main(string[] args)
{
int userId = 0;
Tuple<string, string> userData = GetUserData(userId);
}
public static Tuple<string, string> GetUserData(int userId)
{
return new Tuple<string, string>("Hello", "World");
}
Tuple<bool, T> TryParse<T>(string input)
และแทนที่จะต้องใช้พารามิเตอร์เอาต์พุตคุณจะได้รับทั้งสองค่ากลับมาในทูเพิล
ฉันใช้ทูเพิลเพื่อแก้ปัญหา 11 ของ Project Euler :
class Grid
{
public static int[,] Cells = { { 08, 02, 22, // whole grid omitted
public static IEnumerable<Tuple<int, int, int, int>> ToList()
{
// code converts grid to enumeration every possible set of 4 per rules
// code omitted
}
}
ตอนนี้ฉันสามารถแก้ปัญหาทั้งหมดได้ด้วย:
class Program
{
static void Main(string[] args)
{
int product = Grid.ToList().Max(t => t.Item1 * t.Item2 * t.Item3 * t.Item4);
Console.WriteLine("Maximum product is {0}", product);
}
}
ฉันสามารถใช้ประเภทที่กำหนดเองสำหรับสิ่งนี้ แต่มันจะดูเหมือนTupleทุกประการ
ไวยากรณ์ทูเปิลของ C # มีขนาดใหญ่อย่างน่าขันดังนั้นทูเปิลจึงเจ็บปวดที่จะประกาศ และไม่มีการจับคู่รูปแบบดังนั้นจึงต้องใช้ความเจ็บปวด
แต่ในบางครั้งคุณแค่ต้องการจัดกลุ่มวัตถุแบบเฉพาะกิจโดยไม่ต้องสร้างคลาสขึ้นมา ตัวอย่างเช่นสมมติว่าฉันต้องการรวมรายการ แต่ฉันต้องการสองค่าแทนที่จะเป็นค่าเดียว:
// sum and sum of squares at the same time
var x =
Enumerable.Range(1, 100)
.Aggregate((acc, x) => Tuple.Create(acc.Item1 + x, acc.Item2 + x * x));
แทนที่จะรวมคอลเล็กชันของค่าไว้ในผลลัพธ์เดียวให้ขยายผลลัพธ์เดียวให้เป็นคอลเล็กชันของค่า วิธีที่ง่ายที่สุดในการเขียนฟังก์ชันนี้คือ:
static IEnumerable<T> Unfold<T, State>(State seed, Func<State, Tuple<T, State>> f)
{
Tuple<T, State> res;
while ((res = f(seed)) != null)
{
yield return res.Item1;
seed = res.Item2;
}
}
f
แปลงสถานะบางส่วนเป็นทูเพิล เราคืนค่าแรกจากทูเปิลและตั้งค่าสถานะใหม่เป็นค่าที่สอง สิ่งนี้ช่วยให้เราสามารถรักษาสถานะไว้ได้ตลอดการคำนวณ
คุณใช้มันดังนี้:
// return 0, 2, 3, 6, 8
var evens =
Unfold(0, state => state < 10 ? Tuple.Create(state, state + 2) : null)
.ToList();
// returns 0, 1, 1, 2, 3, 5, 8, 13, 21, 34
var fibs =
Unfold(Tuple.Create(0, 1), state => Tuple.Create(state.Item1, Tuple.Create(state.Item2, state.Item1 + state.Item2)))
.Take(10).ToList();
evens
ค่อนข้างตรงไปตรงมา แต่fibs
ฉลาดกว่าเล็กน้อย state
แท้จริงแล้วมันคือทูเปิลที่มีเส้นใย (n-2) และเส้นใย (n-1) ตามลำดับ
new Tuple<Guid,string,...>
ฉันไม่ชอบการใช้งานในทางที่ผิดเนื่องจากพวกเขาผลิตโค้ดที่ไม่ได้อธิบายตัวเอง แต่มันยอดเยี่ยมในการใช้คีย์ผสมแบบ on-the-fly เนื่องจากพวกเขาใช้ IStructuralEquatable และ IStructuralComparable (เพื่อใช้ทั้งในการค้นหาและสั่งซื้อ วัตถุประสงค์)
และรวมรหัสแฮชของรายการทั้งหมดไว้ภายใน ตัวอย่างเช่นนี่คือ GetHashCode ของ Tuple (นำมาจาก ILSpy):
int IStructuralEquatable.GetHashCode(IEqualityComparer comparer)
{
return Tuple.CombineHashCodes(comparer.GetHashCode(this.m_Item1), comparer.GetHashCode(this.m_Item2), comparer.GetHashCode(this.m_Item3));
}
Tuples เหมาะอย่างยิ่งสำหรับการดำเนินการ async IO หลายรายการพร้อมกันและคืนค่าทั้งหมดเข้าด้วยกัน นี่คือตัวอย่างของการทำด้วยและไม่มี Tuple Tuples สามารถทำให้โค้ดของคุณชัดเจนขึ้นได้จริง!
ไม่มี (รังที่น่ารังเกียจ!):
Task.Factory.StartNew(() => data.RetrieveServerNames())
.ContinueWith(antecedent1 =>
{
if (!antecedent1.IsFaulted)
{
ServerNames = KeepExistingFilter(ServerNames, antecedent1.Result);
Task.Factory.StartNew(() => data.RetrieveLogNames())
.ContinueWith(antecedent2 =>
{
if (antecedent2.IsFaulted)
{
LogNames = KeepExistingFilter(LogNames, antecedent2.Result);
Task.Factory.StartNew(() => data.RetrieveEntryTypes())
.ContinueWith(antecedent3 =>
{
if (!antecedent3.IsFaulted)
{
EntryTypes = KeepExistingFilter(EntryTypes, antecedent3.Result);
}
});
}
});
}
});
ด้วย Tuple
Task.Factory.StartNew(() =>
{
List<string> serverNames = data.RetrieveServerNames();
List<string> logNames = data.RetrieveLogNames();
List<string> entryTypes = data.RetrieveEntryTypes();
return Tuple.Create(serverNames, logNames, entryTypes);
}).ContinueWith(antecedent =>
{
if (!antecedent.IsFaulted)
{
ServerNames = KeepExistingFilter(ServerNames, antecedent.Result.Item1);
LogNames = KeepExistingFilter(LogNames, antecedent.Result.Item2);
EntryTypes = KeepExistingFilter(EntryTypes, antecedent.Result.Item3);
}
});
หากคุณใช้ฟังก์ชันนิรนามกับประเภทโดยนัยอยู่แล้วคุณจะไม่ทำให้รหัสชัดเจนน้อยลงโดยใช้ Tuple การปรับค่า Tuple จากวิธีการใหม่หรือไม่? ใช้เท่าที่จำเป็นเมื่อความชัดเจนของรหัสเป็นกุญแจสำคัญในความเห็นที่ต่ำต้อยของฉัน ฉันรู้ว่าการเขียนโปรแกรมเชิงฟังก์ชันใน C # นั้นยากที่จะต้านทาน แต่เราต้องพิจารณาโปรแกรมเมอร์ C # "เชิงวัตถุ" แบบเก่า ๆ ทั้งหมด
Tuples ถูกใช้อย่างมากในภาษาที่ใช้งานได้ซึ่งสามารถทำสิ่งต่างๆได้มากขึ้นตอนนี้ F # เป็นภาษา. net 'ทางการ' ที่คุณอาจต้องการทำงานร่วมกับมันจาก C # และส่งต่อระหว่างโค้ดที่เขียนในสองภาษา
ฉันมักจะหลีกเลี่ยงTuple
สถานการณ์ส่วนใหญ่เพราะมันทำให้อ่านไม่เข้าใจ อย่างไรก็ตามTuple
มีประโยชน์เมื่อคุณต้องการจัดกลุ่มข้อมูลที่ไม่เกี่ยวข้อง
ตัวอย่างเช่นสมมติว่าคุณมีรายชื่อรถยนต์และเมืองที่ซื้อ:
Mercedes, Seattle
Mustang, Denver
Mercedes, Seattle
Porsche, Seattle
Tesla, Seattle
Mercedes, Seattle
คุณต้องการรวมจำนวนรถแต่ละคันต่อเมือง:
Mercedes, Seattle [3]
Mustang, Denver [1]
Porsche, Seattle [1]
Tesla, Seattle [1]
ในการดำเนินการนี้ให้คุณสร้างไฟล์Dictionary
. คุณมีทางเลือกไม่กี่ทาง:
Dictionary<string, Dictionary<string, int>>
.Dictionary<CarAndCity, int>
.Dictionary<Tuple<string, string>, int>
.ความสามารถในการอ่านจะหายไปด้วยตัวเลือกแรก จะทำให้คุณต้องเขียนโค้ดมากขึ้น
ตัวเลือกที่สองใช้งานได้และกระชับ แต่รถยนต์และเมืองไม่เกี่ยวข้องกันจริงๆและอาจไม่ได้อยู่ในชั้นเรียนด้วยกัน
ตัวเลือกที่สามกระชับและสะอาด Tuple
มันใช้ประโยชน์จาก
ตัวอย่างบางส่วนจากด้านบนของหัวของฉัน:
ตัวอย่างเช่นคุณไม่ต้องการรวม System.Drawing ไว้ในเว็บแอปพลิเคชันเพียงเพื่อใช้ Point / PointF และ Size / SizeF
Tuple
มีประโยชน์พอ ๆ กับสถานการณ์ที่สำคัญPoint
หรือSomeVector
อาจเป็นประโยชน์เมื่อทำงานกราฟิก มันเน้นคุณค่าสองอย่างที่เชื่อมโยงกันมาก ฉันมักจะเห็นคุณสมบัติที่ชื่อ StartTime และ EndTime เมื่ออ่านโค้ด แต่จะดีกว่าเวลาวันที่และระยะเวลา Tuple บังคับให้คุณพิจารณาทั้งสองค่าทุกครั้งที่คุณดำเนินการในส่วนนี้ของตรรกะทางธุรกิจของคุณ หรือส่งคืน "เดี๋ยวก่อนข้อมูลมีการเปลี่ยนแปลง (บูล) นี่คือข้อมูล (ประเภทอื่น)" ในการประมวลผลหนักแทนที่จะใช้การเชื่อมโยงแบบเข้มข้น
คุณควรระมัดระวังในการใช้Tuple
และอาจคิดให้ดีก่อนทำสิ่งนี้ จากประสบการณ์ก่อนหน้านี้ฉันพบว่าการใช้Tuple
โค้ดทำให้อ่านยากมากและรองรับในอนาคต เมื่อไม่นานมานี้ฉันต้องแก้ไขโค้ดบางอย่างที่มีการใช้ tuples เกือบทุกที่ แทนที่จะคิดเกี่ยวกับโมเดลวัตถุที่เหมาะสมพวกเขาใช้เพียงสิ่งทอ นั่นคือฝันร้าย ... บางครั้งฉันก็อยากจะฆ่าคนที่เขียนโค้ด ...
ไม่อยากบอกว่าคุณไม่ควรใช้Tuple
มันชั่วร้ายหรืออะไรบางอย่างและฉันมั่นใจร้อยเปอร์เซ็นต์ว่ามีงานบางอย่างที่Tuple
เป็นตัวเลือกที่ดีที่สุดที่จะใช้ แต่คุณควรคิดอีกครั้งว่าคุณต้องการหรือไม่จริงๆ เหรอ?
การใช้ Tuples ที่ดีที่สุดที่ฉันพบคือเมื่อต้องการส่งคืนอ็อบเจ็กต์มากกว่า 1 ประเภทจากเมธอดคุณจะรู้ว่าอ็อบเจ็กต์ประเภทใดและหมายเลขที่จะเป็นอย่างไรและไม่ใช่รายการที่ยาว
ทางเลือกง่ายๆอื่น ๆ คือการใช้พารามิเตอร์ 'out'
private string MyMethod(out object)
หรือทำพจนานุกรม
Dictionary<objectType1, objectType2>
อย่างไรก็ตามการใช้ Tuple จะช่วยประหยัดทั้งการสร้างอ็อบเจกต์ 'out' หรือต้องค้นหารายการในพจนานุกรมเป็นหลัก
เพิ่งพบวิธีแก้ปัญหาของฉันใน Tuple มันเหมือนกับการประกาศคลาสในขอบเขตของเมธอด แต่ขี้เกียจประกาศชื่อฟิลด์ คุณดำเนินการกับคอลเลกชันของทูเปิลอินสแตนซ์เดียวจากนั้นสร้างคอลเลกชันของประเภทที่ไม่ระบุชื่อด้วยชื่อฟิลด์ที่ต้องการโดยพิจารณาจากทูเปิลของคุณ สิ่งนี้จะหลีกเลี่ยงไม่ให้คุณสร้างคลาสใหม่เพื่อจุดประสงค์นี้
งานคือการเขียนการตอบสนอง JSON จาก LINQ โดยไม่มีคลาสเพิ่มเติม:
//I select some roles from my ORM my with subrequest and save results to Tuple list
var rolesWithUsers = (from role in roles
select new Tuple<string, int, int>(
role.RoleName,
role.RoleId,
usersInRoles.Where(ur => ur.RoleId == role.RoleId).Count()
));
//Then I add some new element required element to this collection
var tempResult = rolesWithUsers.ToList();
tempResult.Add(new Tuple<string, int, int>(
"Empty",
-1,
emptyRoleUsers.Count()
));
//And create a new anonimous class collection, based on my Tuple list
tempResult.Select(item => new
{
GroupName = item.Item1,
GroupId = item.Item2,
Count = item.Item3
});
//And return it in JSON
return new JavaScriptSerializer().Serialize(rolesWithUsers);
ด้วยเหตุนี้เราสามารถทำได้ด้วยการประกาศคลาสใหม่สำหรับกลุ่มของฉัน แต่มีความคิดที่จะสร้างคอลเล็กชันที่ไม่เป็นตัวตนโดยไม่ต้องประกาศคลาสใหม่
ในกรณีของฉันฉันต้องใช้ Tuple เมื่อฉันพบว่าเราไม่สามารถใช้พารามิเตอร์ out ในวิธีอะซิงโครนัสได้ อ่านเกี่ยวกับเรื่องนี้ที่นี่ ฉันต้องการผลตอบแทนประเภทอื่นด้วย ดังนั้นฉันจึงใช้ Tuple แทนเป็นประเภทการส่งคืนของฉันและทำเครื่องหมายวิธีการเป็น async
โค้ดตัวอย่างด้านล่าง
...
...
// calling code.
var userDetails = await GetUserDetails(userId);
Console.WriteLine("Username : {0}", userDetails.Item1);
Console.WriteLine("User Region Id : {0}", userDetails.Item2);
...
...
private async Tuple<string,int> GetUserDetails(int userId)
{
return new Tuple<string,int>("Amogh",105);
// Note that I can also use the existing helper method (Tuple.Create).
}
อ่านเพิ่มเติมเกี่ยวกับTuple ที่นี่ หวังว่านี่จะช่วยได้
การเปลี่ยนรูปร่างของวัตถุเมื่อคุณต้องการส่งผ่านสายหรือส่งผ่านไปยังชั้นของแอปพลิเคชันที่แตกต่างกันและวัตถุหลายชิ้นจะรวมเข้าเป็นหนึ่งเดียว:
ตัวอย่าง:
var customerDetails = new Tuple<Customer, List<Address>>(mainCustomer, new List<Address> {mainCustomerAddress}).ToCustomerDetails();
วิธีการขยาย:
public static CustomerDetails ToCustomerDetails(this Tuple<Website.Customer, List<Website.Address>> customerAndAddress)
{
var mainAddress = customerAndAddress.Item2 != null ? customerAndAddress.Item2.SingleOrDefault(o => o.Type == "Main") : null;
var customerDetails = new CustomerDetails
{
FirstName = customerAndAddress.Item1.Name,
LastName = customerAndAddress.Item1.Surname,
Title = customerAndAddress.Item1.Title,
Dob = customerAndAddress.Item1.Dob,
EmailAddress = customerAndAddress.Item1.Email,
Gender = customerAndAddress.Item1.Gender,
PrimaryPhoneNo = string.Format("{0}", customerAndAddress.Item1.Phone)
};
if (mainAddress != null)
{
customerDetails.AddressLine1 =
!string.IsNullOrWhiteSpace(mainAddress.HouseName)
? mainAddress.HouseName
: mainAddress.HouseNumber;
customerDetails.AddressLine2 =
!string.IsNullOrWhiteSpace(mainAddress.Street)
? mainAddress.Street
: null;
customerDetails.AddressLine3 =
!string.IsNullOrWhiteSpace(mainAddress.Town) ? mainAddress.Town : null;
customerDetails.AddressLine4 =
!string.IsNullOrWhiteSpace(mainAddress.County)
? mainAddress.County
: null;
customerDetails.PostCode = mainAddress.PostCode;
}
...
return customerDetails;
}
พารามิเตอร์ out จะดีมากเมื่อมีค่าเพียงไม่กี่ค่าที่ต้องส่งคืน แต่เมื่อคุณเริ่มพบค่า 4, 5, 6 หรือมากกว่าที่ต้องส่งคืนค่านั้นจะดูเทอะทะ อีกทางเลือกหนึ่งสำหรับการคืนค่าหลายค่าคือการสร้างและส่งคืนคลาส / โครงสร้างที่ผู้ใช้กำหนดเองหรือใช้ทูเพิลเพื่อจัดแพ็กเกจค่าทั้งหมดที่ต้องส่งคืนโดยวิธีการ
ตัวเลือกแรกโดยใช้คลาส / โครงสร้างเพื่อส่งคืนค่านั้นตรงไปตรงมา เพียงแค่สร้างประเภท (ในตัวอย่างนี้เป็นโครงสร้าง) ดังนี้:
public struct Dimensions
{
public int Height;
public int Width;
public int Depth;
}
ตัวเลือกที่สองโดยใช้ Tuple เป็นโซลูชันที่หรูหรายิ่งกว่าการใช้วัตถุที่กำหนดโดยผู้ใช้ สามารถสร้างทูเพิลเพื่อเก็บค่าประเภทต่างๆจำนวนเท่าใดก็ได้ นอกจากนี้ข้อมูลที่คุณจัดเก็บไว้ใน Tuple นั้นไม่เปลี่ยนรูป เมื่อคุณเพิ่มข้อมูลไปยัง Tuple ผ่านตัวสร้างหรือวิธีการสร้างแบบคงที่ข้อมูลนั้นจะไม่สามารถเปลี่ยนแปลงได้ Tuples สามารถรับค่าได้ถึงแปดค่าที่แยกจากกัน หากคุณต้องการส่งคืนค่ามากกว่าแปดค่าคุณจะต้องใช้คลาส Tuple พิเศษ: Tuple Class เมื่อสร้าง Tuple ที่มีมากกว่าแปดค่าคุณจะไม่สามารถใช้วิธีการสร้างแบบคงที่ได้คุณต้องใช้ตัวสร้างของคลาสแทน นี่คือวิธีที่คุณจะสร้างค่า Tuple จากจำนวนเต็ม 10:
var values = new Tuple<int, int, int, int, int, int, int, Tuple<int, int, int>> (
1, 2, 3, 4, 5, 6, 7, new Tuple<int, int, int> (8, 9, 10));
แน่นอนคุณสามารถเพิ่ม Tuples เพิ่มเติมต่อไปได้ในตอนท้ายของ Tuple ที่ฝังแต่ละตัวโดยสร้าง Tuple ขนาดใดก็ได้ที่คุณต้องการ
สำหรับการสร้างต้นแบบเท่านั้น - ทูเปิลไม่มีความหมาย สะดวกในการใช้ แต่เป็นทางลัดเท่านั้น! สำหรับต้นแบบ - ดี อย่าลืมลบรหัสนี้ในภายหลัง
เขียนง่ายอ่านยาก ไม่มีข้อได้เปรียบที่มองเห็นได้เหนือชั้นเรียนชั้นในชั้นเรียนที่ไม่ระบุตัวตนเป็นต้น
ฉันลอง 3 วิธีในการแก้ปัญหาเดียวกันใน C # 7 และฉันพบกรณีการใช้งานสำหรับทูเปิล
การทำงานกับข้อมูลแบบไดนามิกในโครงการเว็บบางครั้งอาจเป็นเรื่องยากลำบากเมื่อทำแผนที่เป็นต้น
ฉันชอบวิธีที่ Tuple แมปโดยอัตโนมัติกับ item1, item2, itemN ซึ่งดูเหมือนว่าจะมีประสิทธิภาพสำหรับฉันมากกว่าการใช้ดัชนีอาร์เรย์ที่คุณอาจถูกจับในรายการที่ไม่อยู่ในดัชนีหรือใช้ประเภทที่ไม่ระบุตัวตนซึ่งคุณอาจสะกดชื่อคุณสมบัติผิด
รู้สึกเหมือน DTO ถูกสร้างขึ้นฟรีโดยใช้ Tuple และฉันสามารถเข้าถึงคุณสมบัติทั้งหมดโดยใช้ itemN ซึ่งให้ความรู้สึกเหมือนการพิมพ์แบบคงที่โดยไม่ต้องสร้าง DTO แยกต่างหากเพื่อจุดประสงค์นั้น
using System;
namespace Playground
{
class Program
{
static void Main(string[] args)
{
var tuple = GetTuple();
Console.WriteLine(tuple.Item1);
Console.WriteLine(tuple.Item2);
Console.WriteLine(tuple.Item3);
Console.WriteLine(tuple);
Console.WriteLine("---");
var dyn = GetDynamic();
Console.WriteLine(dyn.First);
Console.WriteLine(dyn.Last);
Console.WriteLine(dyn.Age);
Console.WriteLine(dyn);
Console.WriteLine("---");
var arr = GetArray();
Console.WriteLine(arr[0]);
Console.WriteLine(arr[1]);
Console.WriteLine(arr[2]);
Console.WriteLine(arr);
Console.Read();
(string, string, int) GetTuple()
{
return ("John", "Connor", 1);
}
dynamic GetDynamic()
{
return new { First = "John", Last = "Connor", Age = 1 };
}
dynamic[] GetArray()
{
return new dynamic[] { "John", "Connor", 1 };
}
}
}
}