// Union - اجتماع (بدون تکرار)
var union = listA.Union(listB);
Console.WriteLine($"Union: {string.Join(", ", union)}"); // 1,2,3,4,5,6,7,8,9
// Intersect - اشتراک
var intersect = listA.Intersect(listB);
Console.WriteLine($"Intersect: {string.Join(", ", intersect)}"); // 4,5,6
// Except - تفاضل (موجود در A ولی نه در B)
var except = listA.Except(listB);
Console.WriteLine($"Except (A - B): {string.Join(", ", except)}"); // 1,2,3
مثال با اشیاء (استفاده از IEqualityComparer):
csharp
class Product
{
public int Id { get; set; }
public string Name { get; set; }
}
List<Product> products1 = new List<Product>
{
new Product { Id = 1, Name = "Laptop" },
new Product { Id = 2, Name = "Mouse" },
new Product { Id = 3, Name = "Keyboard" }
};
List<Product> products2 = new List<Product>
{
new Product { Id = 2, Name = "Mouse" },
new Product { Id = 3, Name = "Keyboard" },
new Product { Id = 4, Name = "Monitor" }
};
// Intersect با اشیاء (نیاز به مقایسهکننده)
var commonProducts = products1.Intersect(products2, new ProductComparer());
Console.WriteLine("\n=== Common Products ===");
foreach (var p in commonProducts)
{
Console.WriteLine(p.Name);
}
class ProductComparer : IEqualityComparer<Product>
{
public bool Equals(Product x, Product y)
{
return x.Id == y.Id;
}
public int GetHashCode(Product obj)
{
return obj.Id.GetHashCode();
}
}
---
⏱️ قسمت 5: متد Zip (ترکیب دو لیست)
Zip دو لیست را عنصر به عنصر با هم ترکیب میکند.
csharp
List<string> names = new List<string> { "Ali", "Sara", "Reza", "Neda" };
List<int> ages = new List<int> { 25, 30, 22, 28 };
List<string> cities = new List<string> { "Tehran", "Shiraz", "Isfahan" };
// Zip دو تایی
var nameAge = names.Zip(ages, (name, age) => $"{name} is {age} years old");
Console.WriteLine("=== Zip (Name + Age) ===");
foreach (var item in nameAge)
{
Console.WriteLine(item);
}
// Zip سه تایی (با استفاده از Zip تو در تو)
var nameAgeCity = names
.Zip(ages, (name, age) => new { name, age })
.Zip(cities, (combined, city) => $"{combined.name} is {combined.age} years old from {city}");
Console.WriteLine("\n=== Zip (Name + Age + City) ===");
foreach (var item in nameAgeCity)
{
Console.WriteLine(item);
}
---
⏱️ قسمت 6: اجرای دیررس (Deferred) در مقابل اجرای فوری (Immediate)
csharp
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// اجرای دیررس (Deferred) - تا زمانی که به نتیجه نیاز نباشد، اجرا نمیشود
var deferredQuery = numbers.Where(n =>
{
Console.WriteLine($"Checking {n}");
return n > 2;
});
Console.WriteLine("Query defined, but not executed yet...");
Console.WriteLine("Now executing with ToList():");
var resultList = deferredQuery.ToList(); // اینجا اجرا میشود
// اجرای فوری (Immediate) - بلافاصله اجرا میشود
Console.WriteLine("\nImmediate execution:");
var immediateResult = numbers
.Where(n => n > 2)
.ToList(); // بلافاصله اجرا میشود
متدهایی که اجرای فوری دارند:
· ToList(), ToArray(), ToDictionary(), ToLookup()
· Count(), Sum(), Average(), Min(), Max()
· First(), FirstOrDefault(), Single(), SingleOrDefault()
csharp
List<int> data = new List<int> { 10, 20, 30, 40, 50 };
// اجرای دیررس
var deferred = data.Where(x => x > 25);
data.Add(60); // اضافه کردن بعد از تعریف query
Console.WriteLine($"Deferred: {string.Join(", ", deferred)}"); // 30,40,50,60
// اجرای فوری
var immediate = data.Where(x => x > 25).ToList();
data.Add(70); // اضافه کردن بعد از ToList
Console.WriteLine($"Immediate: {string.Join(", ", immediate)}"); // 30,40,50,60 (70 اضافه نمیشود)
---
✅ تمرین نهایی درس شانزدهم
برنامهای بنویسید که:
1. دو لیست Customers و Orders بسازد
2. با Join، سفارشهای هر مشتری را نمایش دهد
3. با GroupJoin، مشتریانی که سفارش ندارند را هم نشان دهد
4. با SelectMany، لیست تمام محصولات سفارش داده شده را به صورت تخت نمایش دهد
5. با Union و Intersect، محصولات مشترک بین دو ماه را پیدا کند
csharp
using System;
using System.Collections.Generic;
using System.Linq;
class Customer
{
public int Id { get; set; }
public string Name { get; set; }
public string City { get; set; }
}
class Order
{
public int Id { get; set; }
public int CustomerId { get; set; }
public DateTime Date { get; set; }
public decimal Amount { get; set; }
public List<string> Products { get; set; }
}
class Program
{
static void Main()
{
// دادهها
List<Customer> customers = new List<Customer>
{
new Customer { Id = 1, Name = "Ali Mohammadi", City = "Tehran" },
new Customer { Id = 2, Name = "Sara Ahmadi", City = "Shiraz" },
new Customer { Id = 3, Name = "Reza Karimi", City = "Tehran" },
new Customer { Id = 4, Name = "Neda Hosseini", City = "Isfahan" }
};
List<Order> orders = new List<Order>
{
new Order { Id = 101, CustomerId = 1, Date = DateTime.Now.AddDays(-10), Amount = 1500000,
Products = new List<string> { "Laptop", "Mouse" } },
new Order { Id = 102, CustomerId = 1, Date = DateTime.Now.AddDays(-5), Amount = 250000,
Products = new List<string> { "Keyboard" } },
new Order { Id = 103, CustomerId = 2, Date = DateTime.Now.AddDays(-3), Amount = 85000,
Products = new List<string> { "Book" } },
new Order { Id = 104, CustomerId = 3, Date = DateTime.Now.AddDays(-1), Amount = 5500000,
Products = new List<string> { "Monitor", "Mouse", "Keyboard" } }
};
// 1. Join - سفارشهای هر مشتری
var customerOrders = customers.Join(
orders,
c => c.Id,
o => o.CustomerId,
(c, o) => new { CustomerName = c.Name, OrderId = o.Id, o.Amount, o.Date }
).OrderBy(x => x.CustomerName);
Console.WriteLine("=== Customer Orders (Join) ===");
foreach (var item in customerOrders)
{
Console.WriteLine($"{item.CustomerName}: Order #{item.OrderId} - {item.Amount:C} on {item.Date.ToShortDateString()}");
}
// 2. GroupJoin - مشتریان با لیست سفارشهایشان (حتی بدون سفارش)
var customersWithOrders = customers.GroupJoin(
orders,
c => c.Id,
o => o.CustomerId,
(c, orderList) => new
{
CustomerName = c.Name,
City = c.City,
Orders = orderList,
TotalSpent = orderList.Sum(o => o.Amount),
OrderCount = orderList.Count()
}
);
Console.WriteLine("\n=== Customers with Orders (GroupJoin) ===");
foreach (var c in customersWithOrders)
{
Console.WriteLine($"{c.CustomerName} ({c.City}): {c.OrderCount} orders, Total: {c.TotalSpent:C}");
foreach (var order in c.Orders)
{
Console.WriteLine($" - Order #{order.Id}: {order.Amount:C}");
}
}
// 3. SelectMany - لیست تمام محصولات سفارش داده شده
var allProducts = orders.SelectMany(o => o.Products).Distinct();
Console.WriteLine($"\n=== All Products Ordered ===");
Console.WriteLine(string.Join(", ", allProducts));
// 4. محصولات سفارش داده شده در دو ماه مختلف (مثال با فرض دو دسته سفارش)
var lastWeekProducts = orders
.Where(o => o.Date >= DateTime.Now.AddDays(-7))
.SelectMany(o => o.Products)
.Distinct();
var olderProducts = orders
.Where(o => o.Date < DateTime.Now.AddDays(-7))
.SelectMany(o => o.Products)
.Distinct();
Console.WriteLine("\n=== Products in Last Week ===");
Console.WriteLine(string.Join(", ", lastWeekProducts));
Console.WriteLine("\n=== Products Older than Week ===");
Console.WriteLine(string.Join(", ", olderProducts));
// 5. Union و Intersect
var allUniqueProducts = lastWeekProducts.Union(olderProducts);
var commonProducts = lastWeekProducts.Intersect(olderProducts);
Console.WriteLine($"\n=== All Unique Products: {string.Join(", ", allUniqueProducts)}");
Console.WriteLine($"=== Common Products: {string.Join(", ", commonProducts)}");
// 6. مشتریانی که بیش از یک سفارش دارند
var repeatCustomers = customersWithOrders.Where(c => c.OrderCount > 1);
Console.WriteLine("\n=== Customers with Multiple Orders ===");
foreach (var c in repeatCustomers)
{
Console.WriteLine($"{c.CustomerName}: {c.OrderCount} orders");
}
Console.WriteLine("\nPress Enter to exit...");
Console.ReadLine();
}
}
`--- 📌 جمعبندی درس شانزدهم دسته متدها کاربرد Join Join, GroupJoin ترکیب دو لیست صاف کردن SelectMany تبدیل لیست تو در تو به تخت مجموعه Distinct, Union, Intersect, Except عملیات مجموعهای ترکیب Zip ترکیب عنصر به عنصر اجرا Deferred, Immediate زمان اجرای query نکات مهم: · Join = INNER JOIN در SQL · GroupJoin = LEFT JOIN + GROUP BY · SelectMany = فلَت کردن لیستها · بیشتر متدهای LINQ اجرای دیررس دارند · متدهای ToList, Count, Sum اجرای فوری دارند --- 🧪 تمرین برای شما 1. دو لیست از دانشجویان و نمرات بسازید و با Join ترکیب کنید 2. لیستی از سفارشات با آیتمهایشان بسازید و با SelectMany همه آیتمها را لیست کنید 3. با Union و Intersect، اعداد مشترک بین دو آرایه را پیدا کنید --- 🎉 تبریک! شما LINQ را کامل یاد گرفتید! درسهای LINQ تمام شد: درس عنوان درس 14 LINQ قسمت 1 – متدهای پایه (Where, Select, First) درس 15 LINQ قسمت 2 – مرتبسازی، گروهبندی، محاسبات درس 16 LINQ قسمت 3 – Join و عملگرهای پیشرفته --- اگر این درس را کامل فهمیدید، میتوانیم درس بعدی را شروع کنیم. مباحث پیشنهادی برای ادامه: · درس 17: کار با فایلها (File I/O) · درس 18: Async/Await (برنامهنویسی نامن synchronous) · درس 19: Attribute و Reflection · درس 20: Entity Framework (کار با دیتابیس) بگویید کدام مبحث را میخواهید. سوالی بود بپرسید.