হাসিব, চলো তোমার কোর্সের ৯০ নম্বর লেকচারটি নিয়ে আলোচনা করি। আউটলাইন অনুযায়ী এটি (Section 8: Views - MVC Architecture Pattern) এর অংশ। আগের লেকচারে আমরা Razor View-তে @foreach লুপের ব্যবহার দেখেছি। এই লেকচারে মূলত @for লুপ এবং অন্যান্য লুপ (while, do-while) কীভাবে এবং কেন ব্যবহার করতে হয়, তা নিয়ে আলোচনা করা হয়েছে।

নিচে পুরো লেকচারটির বিস্তারিত ব্রেকডাউন দেওয়া হলো:

📝 Summary (সারসংক্ষেপ)

  • Topic: Razor Views-এ @for, @while, এবং @do-while লুপের ব্যবহার।
  • Core Purpose: একটি HTML tag নির্দিষ্ট সংখ্যক বার রিপিট করা বা কোনো Collection-এর নির্দিষ্ট Index ধরে ডেটা রেন্ডার করা।
  • Why for instead of foreach: foreach লুপ একটি Collection-এর শুরু থেকে শেষ পর্যন্ত পুরোটা রিড করে। কিন্তু যদি তোমার Collection-এর একাংশ (যেমন- শুধু প্রথম ২টি আইটেম), Reverse Order-এ, অথবা নির্দিষ্ট কোনো Index স্কিপ করে ডেটা প্রিন্ট করার প্রয়োজন হয়, তখন for লুপ ব্যবহার করতে হয়।
  • Other Loops: C#-এর সাধারণ while এবং do-while লুপও Razor View-তে কাজ করে, তবে রিয়েল-ওয়ার্ল্ড প্রজেক্টে এগুলোর ব্যবহার খুবই কম।

📌 Razor View-তে @for Loop কেন ব্যবহার করবো? [Priority: 9/10]

C#-এ for এবং foreach লুপের মধ্যে যে মূল পার্থক্য রয়েছে, Razor View-তেও কনসেপ্টটি হুবহু এক।

The “Why” (কেন দরকার): অনেক সময় আমাদের কাছে এমন কিছু Requirement আসে যেখানে foreach লুপ উপযুক্ত নয়। যেমন:

  1. Specific Iteration Count: তোমার কাছে হয়তো কোনো Collection নেই, কিন্তু তুমি একটি বা ট্যাগ ঠিক ৫ বার বা ১০ বার প্রিন্ট করতে চাও।
  2. Partial Collection Traversal: তোমার কাছে ১০০টি আইটেমের একটি Collection আছে, কিন্তু তুমি UI-তে শুধুমাত্র প্রথম ১০টি (Top 10) আইটেম দেখাতে চাও।
  3. Reverse Order: Collection-এর শেষের দিক থেকে ডেটা রিড করে প্রথম দিকে আসতে চাও।
  4. Index Based Access: একটি নির্দিষ্ট Index (যেমন- ৩ নম্বর পজিশন) থেকে শুরু করে ৭ নম্বর পজিশন পর্যন্ত ডেটা দেখাতে চাও।

এই ধরনের সূক্ষ্ম Control-এর জন্য for লুপ ব্যবহার করা হয়।


📌 Code Implementation: @for Loop [Priority: 10/10]

লেকচারে দেখানো উদাহরণ অনুযায়ী, আমাদের কাছে people নামের একটি Collection আছে। foreach ব্যবহার করলে সবার ডেটাই প্রিন্ট হতো। কিন্তু আমরা চাই শুধুমাত্র প্রথম ২ জন Person-এর ডেটা প্রিন্ট করতে।

@{
    // লেকচারের সুবিধার্থে ডেমো ডেটা
    List<Person> people = new List<Person>
    {
        new Person { Name = "John", Gender = "Male" },
        new Person { Name = "Mary", Gender = "Female" },
        new Person { Name = "David", Gender = "Male" }
    };
}
 
<h3>First Two Persons:</h3>
 
<!-- for লুপের শুরুতে @ সিম্বল ব্যবহার করা হয়েছে -->
@for (int i = 0; i < 2; i++)
{
    // Index (i) ব্যবহার করে Collection থেকে নির্দিষ্ট অবজেক্টটি বের করে আনা হচ্ছে
    var person = people[i];
 
    <div class="person-card">
        <span>@person.Name</span>, 
        <span>@person.Gender</span>
    </div>
}
 

কিভাবে কাজ করছে?

  • এখানে লুপটি i = 0 থেকে শুরু হবে এবং i < 2 পর্যন্ত চলবে (অর্থাৎ 0 এবং 1 ইনডেক্সের জন্য)।
  • var person = people[i]; লাইনটি দ্বারা আমরা নির্দিষ্ট Index-এর রেফারেন্সটি একটি Temporary variable-এ রাখছি।
  • এর ফলে Collection-এ ৩টি ডেটা থাকলেও শুধুমাত্র প্রথম ২টি ডেটার জন্য HTML জেনারেট হবে।

📌 @while এবং @do-while Loop [Priority: 3/10]

ইনস্ট্রাক্টর ভিডিওর শেষে উল্লেখ করেছেন যে, শুধু for লুপ নয়, তুমি চাইলে C#-এর while এবং do-while লুপও Razor View-তে ব্যবহার করতে পারো। সিনট্যাক্স সাধারণ C#-এর মতোই, শুধু শুরুতে একটি @ বসাতে হবে।

@{
    int count = 0;
}
 
<!-- while লুপের উদাহরণ -->
@while (count < 3)
{
    <p>This is paragraph number: @count</p>
    count++;
}
 

নোট: Razor View-তে while বা do-while লুপের ব্যবহার খুবই বিরল (Rare)। সাধারণত Collection রেন্ডার করতে foreach বা for লুপই বেশি ব্যবহৃত হয়।


📌 Modern Approach in .NET 10 (Controller vs View Logic) [Priority: 8/10]

যদিও Razor View-তে for লুপ লেখার নিয়ম .NET-এর পুরোনো ভার্সন থেকে .NET 10 পর্যন্ত একই আছে, তবে Modern Architecture-এ View-এর ভেতরে এভাবে লুপের Condition (যেমন i < 2) হার্ডকোড (Hardcode) করাকে ভালো প্র্যাকটিস ধরা হয় না।

.NET 10 এবং আধুনিক MVC প্যাটার্নে লজিক ফিল্টার করার দায়িত্ব Controller-এর, View-এর নয়।

Modern C# Example (The Better Way):

Controller.cs:

public IActionResult Index()
{
    // C# Collection Expression ব্যবহার করা হয়েছে
    List<Person> people = [
        new() { Name = "John", Gender = "Male" },
        new() { Name = "Mary", Gender = "Female" },
        new() { Name = "David", Gender = "Male" }
    ];
 
    // LINQ .Take(2) ব্যবহার করে Controller থেকেই শুধু ২টি ডেটা পাঠানো হচ্ছে
    var topTwoPeople = people.Take(2).ToList(); 
 
    return View(topTwoPeople);
}
 

Index.cshtml (View): যেহেতু Controller আগেই ডেটা ফিল্টার করে দিয়েছে, তাই View-তে এখন আর for লুপ দিয়ে Index হিসাব করার দরকার নেই। আমরা নিশ্চিন্তে ক্লিন @foreach ব্যবহার করতে পারি।

@model IEnumerable<Person>
 
@if (Model is not null && Model.Any())
{
    foreach (var person in Model)
    {
        <div class="person-card">
            <span>@person.Name</span> - <span>@person.Gender</span>
        </div>
    }
}
 

⭐ Best Practices (MVC Views Context)

  1. Avoid Complex Logic in Views: View-এর কাজ শুধু ডেটা প্রেজেন্ট করা। View-এর ভেতরে for লুপ দিয়ে ডেটা ফিল্টারিং (যেমন- প্রথম ২টি বা শেষের ৩টি ডেটা বের করা) করা উচিত নয়। ডেটা ফিল্টার করার কাজটি Controller বা Service Layer-এ LINQ (যেমন- .Take(), .Skip(), .Reverse()) ব্যবহার করে করা উচিত।
  2. Handle IndexOutOfRangeException: for লুপ ব্যবহার করার সময় খেয়াল রাখতে হবে লুপের কন্ডিশন যেন Collection-এর টোটাল সাইজ (Count বা Length) এর চেয়ে বড় না হয়ে যায়। নতুবা অ্যাপ্লিকেশন ক্র্যাশ করবে।
  3. Use foreach by Default: যতক্ষণ না পর্যন্ত তোমার সুনির্দিষ্টভাবে কোনো Index-এর প্রয়োজন হচ্ছে, ততক্ষণ Collection রেন্ডার করার জন্য সবসময় @foreach লুপ ব্যবহার করবে। এটি অনেক বেশি ক্লিন এবং রিডেবল।