.Net Core Fundamentals with C# Primitive and Reference types

.

PART 1 – C# Primitive (Value) Types

✅ What Are Primitive (Value) Types?

Primitive types store the actual value directly in memory (Stack memory).

Each variable has its own independent copy.


🔹 Common Primitive Types

TypeUsed ForBusiness Example
intWhole numbersOrder count
decimalMoney valuesInvoice total
doubleCalculationsAnalytics
boolTrue/FalsePayment status
charSingle characterGrade
DateTimeDate/timeOrder date

Real-Time Business Example – E-Commerce Order

int quantity = 2;
decimal price = 1500m;
decimal totalAmount = quantity * price;

bool isPaid = false;

Why primitive?

  • Quantity is just a number.
  • Total amount is just a value.
  • No need for complex structure.

Important Behavior (Value Copy)

int x = 10;
int y = x;

y = 20;

Console.WriteLine(x); // 10
Console.WriteLine(y); // 20

Each variable has its own copy.

When Should You Use Primitive Types?

Use them when:

✔ You store simple data
✔ You don’t need complex behavior
✔ You want better performance
✔ No object relationship required

Examples:

  • Counting users
  • Calculating salary
  • Checking login status
  • Tracking stock quantity

PART 2 – Reference Types

✅ What Are Reference Types?

Reference types store a memory address (reference), not the actual value.

Actual object lives in Heap memory.


🔹 Common Reference Types

TypeExample
classUser, Order, Product
stringCustomer name
arrayList of products
List<T>Collection of users
objectBase type

Real-Time Business Example – Customer Object

class Customer
{
    public string Name;
    public int Age;
}

Customer c1 = new Customer();
c1.Name = "Jagan";

Customer c2 = c1;
c2.Name = "Raj";

Console.WriteLine(c1.Name); // Raj

Business Scenario – Order Processing

In real-world systems (like your .NET API):\

class Order
{
    public int OrderId;
    public decimal Amount;
}

You use reference type (class) because:

  • It contains multiple properties
  • It represents a real-world entity
  • You may pass it between layers (Controller → Service → Repository)

🔹 When Should You Use Reference Types?

Use them when:

✔ Modeling real-world entities
✔ Storing multiple related values
✔ Passing data between layers
✔ Building APIs / Web apps

Examples:

  • User
  • Product
  • Order
  • Invoice
  • Employee

🔷 Difference: Primitive vs Reference

FeaturePrimitiveReference
MemoryStackHeap
Copy behaviorValue copiedAddress copied
PerformanceFasterSlightly slower
Used forSimple valuesComplex objects

🔷 PART 3 – Conditional Constructs

Used for decision-making.


1️⃣ if Statement

Business Use Case – Login Validation

bool isAuthenticated = true;

if(isAuthenticated)
{
    Console.WriteLine("Access Granted");
}

When to use?

✔ Single condition check
✔ Simple validation


2️⃣ if-else

Business Use Case – Payment Status

bool paymentSuccess = false;

if(paymentSuccess)
{
    Console.WriteLine("Order Confirmed");
}
else
{
    Console.WriteLine("Payment Failed");
}

if-else if Ladder

Business Use Case – Tax Calculation

decimal salary = 80000;

if(salary > 100000)
{
    Console.WriteLine("30% Tax");
}
else if(salary > 50000)
{
    Console.WriteLine("20% Tax");
}
else
{
    Console.WriteLine("10% Tax");
}

When to use?

✔ Multiple range conditions
✔ Business rule validations

switch Statement

Business Use Case – Order Status

string status = "Shipped";

switch(status)
{
    case "Pending":
        Console.WriteLine("Order is pending");
        break;

    case "Shipped":
        Console.WriteLine("Order shipped");
        break;

    default:
        Console.WriteLine("Unknown status");
        break;
}

When to use?

✔ Fixed known values
✔ Cleaner than many if-else

PART 4 – Loops in C#

Loops repeat logic.

1️⃣ for Loop

Used when iteration count is known.

Business Example – Process Orders

for(int i = 1; i <= 5; i++)
{
    Console.WriteLine("Processing Order: " + i);
}

When to use?

✔ Known count
✔ Index-based processing

while Loop

Used when condition-based.

Business Example – Retry Payment

int attempts = 0;

while(attempts < 3)
{
    Console.WriteLine("Retrying Payment...");
    attempts++;
}

while Loop

Used when condition-based.

Business Example – Retry Payment

int attempts = 0;

while(attempts < 3)
{
    Console.WriteLine("Retrying Payment...");
    attempts++;
}

do-while Loop

Runs at least once.

Business Example – ATM Menu

int choice;

do
{
    Console.WriteLine("1. Withdraw");
    Console.WriteLine("2. Exit");
    choice = Convert.ToInt32(Console.ReadLine());

} while(choice != 2);

foreach Loop

Used for collections.

Business Example – List of Customers

string[] customers = { "Ram", "Sam", "Jagan" };

foreach(string customer in customers)
{
    Console.WriteLine(customer);
}

REAL-TIME MINI PROJECT – Billing System

decimal total = 0;

for(int i = 1; i <= 3; i++)
{
    Console.Write("Enter product price: ");
    decimal price = Convert.ToDecimal(Console.ReadLine());
    total += price;
}

if(total > 5000)
{
    total = total * 0.9m; // 10% discount
}

Console.WriteLine("Final Bill: " + total);

Concepts used:

  • Primitive types
  • Loop
  • Condition

When Should You Use What? (Practical Decision Guide)

ScenarioUse
Simple number calculationPrimitive
Real-world entity modelingReference type
Single conditionif
Multiple fixed valuesswitch
Known iteration countfor
Unknown iteration countwhile
Collection traversalforeach

In Enterprise .NET Projects (Real Business)

In real-world systems like:

  • E-commerce
  • Banking
  • Healthcare
  • SaaS platforms
  • Cloud APIs

You will:

✔ Use primitive types for calculations
✔ Use reference types for domain models
✔ Use conditions for business rules
✔ Use loops for batch processing
✔ Combine everything in Controllers & Services

SECTION 2 :Data Structures for .NET Developers

(Concept + When to Use + Business Use Case + Real-Time Example)

As a .NET developer, especially if you’re building APIs, microservices, SaaS apps, or enterprise systems, choosing the right data structure directly impacts performance, scalability, and memory usage.

I’ll explain:

  • ✅ What it is
  • ✅ When to use it
  • ✅ Business use case
  • ✅ Real-time C# example
  • ✅ Performance considerations

1️⃣ Array

🔹 Concept

Fixed-size collection of same data type stored in contiguous memory.

int[] numbers = new int[3] { 10, 20, 30 };

When to Use

✔ Fixed number of items
✔ High performance needed
✔ Index-based access required

Business Use Case

Monthly sales for 12 months.

decimal[] monthlySales = new decimal[12];
monthlySales[0] = 100000m; // January

Performance

  • Access: O(1)
  • Insert/Delete: Not flexible

2️⃣ List<T>

🔹 Concept

Dynamic version of Array (Resizable collection).

List<string> users = new List<string>();
users.Add("Jagan");

When to Use

✔ Data size unknown
✔ Frequent add/remove
✔ API responses

Business Use Case

Fetching users from database.

List<string> customers = new List<string>
{
    "Ram",
    "Sam",
    "Jagan"
};

Why Used in Enterprise?

Most commonly used structure in:

  • ASP.NET Core APIs
  • EF Core queries
  • Microservices responses

2.Dictionary<TKey, TValue>

🔹 Concept

Stores data as key-value pairs.
Fast lookups.

Dictionary<int, string> employees = new Dictionary<int, string>();
employees.Add(101, "Raj");

When to Use

✔ Fast searching by key
✔ Mapping relationships
✔ Caching

Business Use Case – Product Lookup

Dictionary<int, string> productCatalog = new Dictionary<int, string>
{
    {1, "Laptop"},
    {2, "Mobile"}
};

Console.WriteLine(productCatalog[1]); // Laptop

Performance

  • Lookup: O(1)
  • Ideal for high-performance APIs

4.HashSet<T>

🔹 Concept

Stores unique values only.

HashSet<string> emails = new HashSet<string>();
emails.Add("user@gmail.com");

When to Use

✔ Avoid duplicates
✔ Fast existence check

Business Use Case

Prevent duplicate registrations.

if(!emails.Contains("user@gmail.com"))
{
    emails.Add("user@gmail.com");
}

5.Stack<T>

🔹 Concept

LIFO (Last In First Out)

Stack<string> history = new Stack<string>();
history.Push("Page1");

history.Push("Page2");
history.Push("Page3");

Console.WriteLine("=== STACK CONTENT (Top to Bottom) ===");

foreach (var page in history)
{
    Console.WriteLine(page);
}

Console.WriteLine("\nPeek (Top Item): " + history.Peek());

Console.WriteLine("\nPopping Items:");

while (history.Count > 0)
{
    Console.WriteLine("Removed: " + history.Pop());
}

When to Use

✔ Undo/Redo
✔ Navigation history
✔ Recursive operations

Business Use Case

Browser back button.

history.Push("Home");
history.Push("Products");

Console.WriteLine(history.Pop()); // Products

Queue<T>

🔹 Concept

FIFO (First In First Out)

Queue<string> supportTickets = new Queue<string>();

// Add multiple tickets
supportTickets.Enqueue("Ticket1");
supportTickets.Enqueue("Ticket2");
supportTickets.Enqueue("Ticket3");
supportTickets.Enqueue("Ticket4");

Console.WriteLine("=== ALL TICKETS IN QUEUE (Front to Rear) ===");

foreach (var ticket in supportTickets)
{
    Console.WriteLine(ticket);
}

Console.WriteLine("\nNext Ticket To Process (Peek): " + supportTickets.Peek());

Console.WriteLine("\nProcessing Tickets...");

while (supportTickets.Count > 0)
{
    Console.WriteLine("Resolved: " + supportTickets.Dequeue());
}

Console.WriteLine("\nRemaining Tickets Count: " + supportTickets.Count);

When to Use

✔ Task processing
✔ Request queues
✔ Order processing


🔹 Business Use Case

Customer support system.

Console.WriteLine(supportTickets.Dequeue());

7.LinkedList<T>

🔹 Concept

Nodes connected via pointers.

  • In-memory caching layer
  • API rate limiter
  • Session management system

You need:

  • Fast removal of oldest item
  • Fast move-to-front operation

Scenario

  • Playlist reordering
  • Priority adjustment
  • Real-time job scheduling

If you already have the node reference:

LinkedList browserHistory = new LinkedList();

   LinkedList<string> browserHistory = new LinkedList<string>();

        // Adding pages
        browserHistory.AddLast("Home");
        browserHistory.AddLast("Products");
        browserHistory.AddLast("Cart");

        // Insert page after Products
        var productsNode = browserHistory.Find("Products");
        if (productsNode != null)
        {
            browserHistory.AddAfter(productsNode, "Offers");
        }

        // Remove Cart page
        browserHistory.Remove("Cart");

        string output = "=== BROWSER HISTORY (Forward) ===\n";

        foreach (var page in browserHistory)
        {
            output += page + "\n";
        }

        output += "\n=== BROWSER HISTORY (Backward) ===\n";

        var current = browserHistory.Last;
        while (current != null)
        {
            output += current.Value + "\n";
            current = current.Previous;
        }

        Console.WriteLine(output);

        // Write to file
        File.WriteAllText("LinkedListOutput.txt", output);

        Console.WriteLine("\nOutput written to LinkedListOutput.txt");
    }

When to Use

✔ Frequent insert/delete
✔ Large dynamic datasets

Business Use Case

Playlist system where songs inserted frequently.

8.Concurrent Collections (Enterprise Level)

For multithreaded apps.

Examples:

  • ConcurrentDictionary
  • ConcurrentQueue

Used in:

  • High traffic APIs
  • Microservices
  • Background jobs

Real-World Enterprise Scenario (.NET API)

Imagine you build:

✅ E-commerce API
✅ Banking system
✅ SaaS platform

You might use:

ScenarioData Structure
Fetch ordersList<Order>
Cache productDictionary<int, Product>
Prevent duplicate emailsHashSet<string>
Background processingQueue<Order>
Undo transactionsStack<Transaction>

Concept-Focused Comparison

StructureBest ForPerformance
ArrayFixed dataFast
ListDynamic dataFlexible
DictionaryKey lookupVery fast
HashSetUnique valuesFast
StackLIFOControlled
QueueFIFOSequential

When NOT to Use

❌ Don’t use List if frequent lookups by key → use Dictionary
❌ Don’t use Array if size unknown
❌ Don’t use Dictionary if order matters
❌ Don’t use Stack for random access

Advanced Enterprise Insight (Important for Architects)

In large systems (like AWS-hosted microservices or SaaS apps):

  • API Response → List<T>
  • In-memory caching → Dictionary
  • Redis alternative → Dictionary
  • Background worker → Queue
  • Idempotency check → HashSet

SECTION 3: Implementation & Usage of List<T>, Dictionary<TKey,TValue>, Queue<T> and LINQ

(Concept + Real-Time Business Example + When to Use + Performance + Pros & Cons)

This is practical, enterprise-level guidance for .NET developers building:

  • ASP.NET Core APIs
  • Microservices
  • SaaS platforms
  • High-performance backend systems

1️⃣ List<T>


🔹 Concept

List<T> is a dynamic array.
It resizes automatically when elements are added.

Internally:

Doubles capacity when full

Backed by array

List<int> numbers = new List<int>();
numbers.Add(10);
numbers.Add(20);

Real-Time Business Example – Order Management API

Imagine you fetch orders from database.

public class Order
{
    public int OrderId { get; set; }
    public decimal Amount { get; set; }
}

List<Order> orders = new List<Order>
{
    new Order { OrderId = 1, Amount = 1000 },
    new Order { OrderId = 2, Amount = 2500 }
};

When to Use

✔ When data size is unknown
✔ When order matters
✔ When returning collections from API
✔ When iteration is common

Used in:

  • GetAllUsers()
  • GetOrders()
  • EF Core .ToList()

Performance

OperationTime Complexity
Access by indexO(1)
Add (end)O(1) average
Insert/Delete middleO(n)
SearchO(n)

Performance Optimization

Avoid repeated resizing

List<Order> orders = new List<Order>(1000); // Pre-allocate capacity

Pros

✔ Simple
✔ Maintains order
✔ Fast indexed access
✔ LINQ friendly


🔹 Cons

❌ Slow lookup
❌ Insert/delete in middle costly
❌ Not ideal for key-based search

Dictionary<TKey, TValue>


🔹 Concept

Stores key-value pairs.
Internally uses Hash Table.

Dictionary<int, string> users = new Dictionary<int, string>();
users.Add(101, "Jagan");

Real-Time Business Example – Product Cache

In high-traffic API:

     List<Order> orders = new List<Order>
    {
        new Order { OrderId = 1, Amount = 1000 },
        new Order { OrderId = 2, Amount = 2500 }
    };

    Dictionary<int, Order> orderCache = new Dictionary<int, Order>();

    foreach (var ord in orders)
    {
        orderCache[ord.OrderId] = ord;
    }

    // Fast lookup
    var order = orderCache[1];

    Console.WriteLine("=== FAST LOOKUP RESULT ===");
    Console.WriteLine("Order ID: " + order.OrderId);
    Console.WriteLine("Amount: " + order.Amount);
}

When to Use

✔ Fast lookup required
✔ Unique keys
✔ In-memory caching
✔ Configuration mappings

Used in:

  • JWT claims
  • Product cache
  • Feature flags
  • Id → Entity mapping

🔹 Performance

OperationTime Complexity
AddO(1)
LookupO(1)
RemoveO(1)

Much faster than List search.


🔹 Performance Considerations

  • Keys must be unique
  • Good hash distribution improves speed
  • Avoid large object keys

🔹 Pros

✔ Extremely fast lookup
✔ Ideal for caching
✔ Scalable


🔹 Cons

❌ No guaranteed order (unless using OrderedDictionary)
❌ More memory usage
❌ Requires unique keys


3️⃣ Queue<T>


🔹 Concept

FIFO (First In First Out)

Queue<string> tickets = new Queue<string>();
tickets.Enqueue("Ticket1");
tickets.Dequeue();

Real-Time Business Example – Order Processing Queue

 Queue<Order> orderQueue = new Queue<Order>();

        orderQueue.Enqueue(new Order { OrderId = 1, Amount = 500 });
        orderQueue.Enqueue(new Order { OrderId = 2, Amount = 700 });

        Console.WriteLine("=== ORDER PROCESSING STARTED ===");

        while (orderQueue.Count > 0)
        {
            var order = orderQueue.Dequeue();
            Console.WriteLine($"Processing Order: {order.OrderId}, Amount: {order.Amount}");
        }

        Console.WriteLine("=== ALL ORDERS PROCESSED ===");
    }

When to Use

✔ Task processing
✔ Background workers
✔ Message handling
✔ Rate-limiting systems

Used in:

  • Payment processing
  • Email sending
  • Job scheduling

🔹 Performance

OperationTime Complexity
EnqueueO(1)
DequeueO(1)

Very efficient for sequential processing.


🔹 Pros

✔ Maintains processing order
✔ Efficient
✔ Simple


🔹 Cons

❌ No random access
❌ Not suitable for search


4️⃣ LINQ (Language Integrated Query)


🔹 Concept

LINQ allows querying collections using SQL-like syntax.

var highValueOrders = orders
    .Where(o => o.Amount > 1000)
    .ToList();

Real-Time Business Example – Filtering Orders

var totalRevenue = orders.Sum(o => o.Amount);

var topOrders = orders
    .Where(o => o.Amount > 2000)
    .OrderByDescending(o => o.Amount)
    .ToList();

When to Use

✔ Filtering
✔ Sorting
✔ Grouping
✔ Aggregation

Used heavily in:

  • EF Core
  • API filtering
  • Reporting modules

LINQ Performance Considerations


1️⃣ Deferred Execution

var query = orders.Where(o => o.Amount > 1000);

Query not executed until:

query.ToList();

Be careful inside loops.

2️⃣ Avoid Multiple Enumerations

❌ Bad:

if(orders.Count() > 0)
{
    foreach(var order in orders)

Better:

if(orders.Any())

Avoid LINQ in High-Performance Loops

Instead of:

orders.Where(o => o.Amount > 1000).ToList();

Use manual loop in performance-critical systems.


4️⃣ Use AsNoTracking() in EF Core

Improves performance in read-only queries.

Use AsNoTracking() in EF Core

Improves performance in read-only queries.

Combined Enterprise Example

High Performance API Scenario

// Step 1: Load orders
List<Order> orders = GetOrders();

// Step 2: Convert to dictionary for fast lookup
Dictionary<int, Order> orderLookup =
    orders.ToDictionary(o => o.OrderId);

// Step 3: Process queue
Queue<Order> processingQueue = new Queue<Order>(orders);

// Step 4: Use LINQ for analytics
var totalRevenue = orders.Sum(o => o.Amount);

Business Decision Guide

ScenarioUse
Return list of usersList<T>
Lookup by IDDictionary
Task processingQueue
Filter/reportingLINQ
In-memory cacheDictionary
Sequential processingQueue

Enterprise Architecture Insight

In scalable cloud systems:

  • API layer → List<T>
  • Cache layer → Dictionary
  • Background worker → Queue
  • Reporting → LINQ
  • High throughput systems → Avoid heavy LINQ chaining

🔷 Comparison Summary

FeatureListDictionaryQueue
Lookup SpeedSlowVery FastN/A
Order MaintainedYesNoYes
MemoryModerateHigherLow
Best ForCollectionsMappingProcessing

🔷 Pros & Cons Summary

List

✔ Flexible
❌ Slow lookup

Dictionary

✔ Fast
❌ More memory

Queue

✔ Structured processing
❌ No random access

LINQ

✔ Clean code
❌ Can impact performance if overused

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *