0% found this document useful (0 votes)
2 views7 pages

CSharp HowToWrite BPL-1

The document outlines a step-by-step guide for writing C# object-oriented programming (OOP) code for a cricket system, detailing phases from requirement extraction to code implementation. It includes class hierarchy planning, the creation of abstract and derived classes (Player, Batsman, Bowler, AllRounder), and the use of polymorphism in the main method to display player information. Additionally, it provides expected output examples and quick reference keywords for C# OOP concepts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
2 views7 pages

CSharp HowToWrite BPL-1

The document outlines a step-by-step guide for writing C# object-oriented programming (OOP) code for a cricket system, detailing phases from requirement extraction to code implementation. It includes class hierarchy planning, the creation of abstract and derived classes (Player, Batsman, Bowler, AllRounder), and the use of polymorphism in the main method to display player information. Additionally, it provides expected output examples and quick reference keywords for C# OOP concepts.
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as DOCX, PDF, TXT or read online on Scribd

How to Write C# OOP Code — BPL Cricket System

Step-by-step: from reading the question → planning → writing every line of code

What to do & why Code to write

PHASE 1 — READ THE QUESTION AND EXTRACT REQUIREMENTS


What is the question asking? From the question, extract 4 things:
Read every sentence. Underline: class names, fields, conditions, 1. Classes: Player, Batsman, Bowler, AllRounder
rules. 2. Fields: runs, avg, highScore, wickets, bowlingAvg
3. Method: PlayerPerformance() → returns bool (eligible or not)
4. Rules:
Batsman: avg > 50
Bowler: wickets > 100
AllRounder: runs > 1000 AND wickets > 50

PHASE 2 — PLAN THE CLASS HIERARCHY BEFORE TOUCHING THE KEYBOARD


Why plan first? Hierarchy map:
If you write code before planning, you'll miss which methods go in Player (abstract base)
which class. ├── fields: PlayerId, PlayerName, TeamName (shared)
Rule of thumb: ├── ShowInfo() → virtual (base prints id/name/team)
└── PlayerPerformance() → abstract (no body here!)
If something is SHARED by all → it goes in the BASE class.
If it's UNIQUE to one type → it goes in THAT subclass. Batsman : Player
│ TotalRuns, BattingAverage, HighestScore
│ PlayerPerformance() → BattingAverage > 50
Bowler : Player
│ TotalWickets, BowlingAverage
│ PlayerPerformance() → TotalWickets > 100
AllRounder : Player
TotalRuns, TotalWickets
PlayerPerformance() → runs>1000 AND wickets>50

PHASE 3 — WRITE THE CODE, ONE PIECE AT A TIME

STEP 1 Start with namespace and using statement


Always the outermost wrapper of any C# program

Why namespace?
A namespace groups your classes together and avoids name
conflicts with other libraries.
using System is needed for [Link]. Without it,
the compiler can't find Console.

using System;

namespace ConsoleAppCricketWorldCup {
// ... all classes go inside here
}

STEP 2 Write the abstract Player base class


abstract = cannot be instantiated. Contains SHARED fields and the abstract method contract.

Why abstract?
abstract means you can NEVER do new Player() directly. A
Player alone makes no sense — you need a specific type.
Auto-properties:
{ get; set; } is shorthand. C# auto-generates the hidden
backing field for you.
Constructor tip:
The base constructor takes id, name, team and assigns them.
Subclasses will call this with : base(...).

// Step 2a — class header with 'abstract' keyword


public abstract class Player {

// Step 2b — shared properties (every player has these)


public string PlayerId { get; set; }
public string PlayerName { get; set; }
public string TeamName { get; set; }

// Step 2c — constructor: assign all three shared fields


public Player(string id, string name, string team) {
PlayerId = id; PlayerName = name; TeamName = team;
}

// Step 2d — virtual ShowInfo: base prints id/name/team


// 'virtual' = subclasses CAN override it
public virtual void ShowInfo() {
[Link]($" ID: {PlayerId} Name: {PlayerName} Team: {TeamName}");
}

// Step 2e — abstract PlayerPerformance: NO body here!


// 'abstract' = subclasses MUST override and implement it
public abstract bool PlayerPerformance();
}

RULE: abstract method has no body (no { }). It's a PROMISE that every subclass will provide their own version. If a subclass doesn't override it, the code won't compile.

vs virtual: virtual has a body (a default implementation). Subclasses CAN override it but don't have to. Here ShowInfo() is virtual because the base prints 3 lines that every subclass
reuses.

STEP 3 Write the Batsman subclass


Adds its own fields, calls base constructor, overrides both methods
Pattern for every subclass:
① class Name : Player
② add its OWN fields
③ constructor calls : base(id, name, team)
④ override ShowInfo() — print [ TYPE ] then call
[Link]() then print own fields
⑤ override PlayerPerformance() with the
eligibility condition
The : base() trick:
Instead of re-assigning PlayerId, PlayerName, TeamName yourself,
you hand them to the parent constructor with : base(id, name,
team).

// Step 3a — inherit from Player


public class Batsman : Player {

// Step 3b — Batsman-specific fields


public double TotalRuns { get; set; }
public double BattingAverage { get; set; }
public double HighestScore { get; set; }

// Step 3c — constructor: take ALL params, pass shared ones to base


public Batsman(string id, string name, string team,
double runs, double avg, double high)
: base(id, name, team) { // ← hands id/name/team to Player constructor
TotalRuns = runs; BattingAverage = avg; HighestScore = high;
}

// Step 3d — override ShowInfo: print type label, call base, print own fields
public override void ShowInfo() {
[Link]("[ BATSMAN ]");
[Link](); // ← runs [Link]() → prints id/name/team
[Link]($" Runs: {TotalRuns} Avg: {BattingAverage} Highest: {HighestScore}");
[Link](PlayerPerformance()
? " Award: ELIGIBLE (Batting Average > 50)"
: " Award: Not Eligible");
}

// Step 3e — override PlayerPerformance: the eligibility rule


// => means 'expression body' — shorthand for { return ...; }
public override bool PlayerPerformance() => BattingAverage > 50;
}

KEY CONCEPT: [Link]() By calling [Link]() inside the override, you REUSE the parent's code. You don't retype the ID/Name/Team lines. This is the whole point of
inheritance — write once, reuse everywhere.

KEY CONCEPT: => (expression body) public override bool PlayerPerformance() => BattingAverage > 50; is identical to writing { return BattingAverage > 50; } — just shorter. Use it
when the whole method is a single expression.

STEP 4 Write the Bowler subclass


Same pattern as Batsman — only fields and condition change

Bowler only has 2 own fields:


TotalWickets and BowlingAverage. Notice no HighestScore
— that was Batsman-specific.
Condition: TotalWickets > 100
The logic is the same pattern. Only the field name and number
change.

public class Bowler : Player {

public double TotalWickets { get; set; }


public double BowlingAverage { get; set; }

// Only 2 own params after the 3 shared ones


public Bowler(string id, string name, string team,
double wkts, double avg)
: base(id, name, team) {
TotalWickets = wkts; BowlingAverage = avg;
}

public override void ShowInfo() {


[Link]("[ BOWLER ]");
[Link]();
[Link]($" Wickets: {TotalWickets} Bowling Avg: {BowlingAverage}");
[Link](PlayerPerformance()
? " Award: ELIGIBLE (Wickets > 100)"
: " Award: Not Eligible");
}

// Condition: wickets > 100


public override bool PlayerPerformance() => TotalWickets > 100;
}

STEP 5 Write the AllRounder subclass


Two conditions joined by && — both must be true

AND condition:
The question says runs > 1000 AND wickets > 50. In C#, AND =
&&. Both must be true for the method to return true.
AllRounder has NO BattingAverage or BowlingAverage.
The question only says runs + wickets. Don't add fields the question
didn't ask for.

public class AllRounder : Player {

// AllRounder tracks runs AND wickets (no average fields)


public double TotalRuns { get; set; }
public double TotalWickets { get; set; }
public AllRounder(string id, string name, string team,
double runs, double wkts)
: base(id, name, team) {
TotalRuns = runs; TotalWickets = wkts;
}

public override void ShowInfo() {


[Link]("[ ALL-ROUNDER ]");
[Link]();
[Link]($" Runs: {TotalRuns} Wickets: {TotalWickets}");
[Link](PlayerPerformance()
? " Award: ELIGIBLE (Runs>1000 AND Wickets>50)"
: " Award: Not Eligible");
}

// && means BOTH conditions must be true


// Sam Curran: runs=781 (fails runs>1000) → Not Eligible even though wickets=60>50
public override bool PlayerPerformance() =>
TotalRuns > 1000 && TotalWickets > 50;
}

PITFALL: && vs || AND (&&): BOTH must be true. Sam Curran has 781 runs (fails runs>1000) so he is NOT eligible even though 60>50 passes. OR (||): EITHER one being true is
enough. This question wants &&, so both must pass.

STEP 6 Write the Main method — create objects and loop


Player[] array holds all 4 players. foreach calls ShowInfo() on each — polymorphism picks the right version automatically.

Player[] array:
Player[] means an array that holds references to Player objects.
But since Batsman, Bowler, AllRounder all inherit Player, they all fit
in this array.
Polymorphism in foreach:
[Link]() — even though player is declared as type
Player, C# looks at the actual object type at runtime and calls the
RIGHT ShowInfo(). This is polymorphism.
Argument order MUST match constructor:
new Batsman(id, name, team, runs, avg, high) — count your
arguments against the constructor signature.

class Program {
static void Main(string[] args) {

// Step 6a — declare array of base type Player (size 4)


Player[] players = new Player[4];

// Step 6b — assign each slot. Arguments follow constructor order.


// Batsman(id, name, team, runs, avg, highScore)
players[0] = new Batsman("P-1", "Tom Latham", "NZ", 6789, 57.3, 183);
// Bowler(id, name, team, wickets, bowlingAvg)
players[1] = new Bowler("P-2", "Taskin Ahmed", "BD", 104, 23.2);

// AllRounder(id, name, team, runs, wickets)


players[2] = new AllRounder("P-3", "Glenn Maxwell", "AUS", 7590, 98);
players[3] = new AllRounder("P-4", "Sam Curran", "Eng", 781, 60);

// Step 6c — foreach: C# automatically calls the right ShowInfo()


// players[0] is a Batsman → calls [Link]()
// players[1] is a Bowler → calls [Link]()
// This is POLYMORPHISM — one loop handles all types
foreach (Player player in players) {
[Link]();
[Link](); // blank line between players
}
}
}

POLYMORPHISM in action: foreach (Player player in players) — [Link]() looks like it would call [Link](). But it actually calls WHICHEVER subclass the object really
is. Batsman at index 0 → [Link]() runs. C# figures this out automatically at runtime. This is why we don't need 4 separate loops.

STEP 7 Close the namespace — final bracket


Every opening { needs a closing }. Check your brackets.

} // closes: namespace ConsoleAppCricketWorldCup

EXPECTED OUTPUT — verify your code produces this exactly

[ BATSMAN ]
ID: P-1 Name: Tom Latham Team: NZ
Runs: 6789 Avg: 57.3 Highest: 183
Award: ELIGIBLE (Batting Average > 50)

[ BOWLER ]
ID: P-2 Name: Taskin Ahmed Team: BD
Wickets: 104 Bowling Avg: 23.2
Award: ELIGIBLE (Wickets > 100)

[ ALL-ROUNDER ]
ID: P-3 Name: Glenn Maxwell Team: AUS
Runs: 7590 Wickets: 98
Award: ELIGIBLE (Runs>1000 AND Wickets>50)

[ ALL-ROUNDER ]
ID: P-4 Name: Sam Curran Team: Eng
Runs: 781 Wickets: 60
Award: Not Eligible ← 781 fails runs>1000
QUICK REFERENCE — C# OOP keywords for exam questions like this
abstract class → Cannot be instantiated. Must be inherited. Contains abstract methods (no body).
: Player → Inherits from Player. Child gets all parent fields and methods.
: base(id,name,team) → Calls the parent constructor. Do this whenever parent has a constructor with params.
virtual → Method HAS a body in parent. Child CAN override it. If not overridden, parent version runs.
abstract method → Method has NO body in parent. Child MUST override it or won't compile.
override → Child is replacing/extending the parent version of a virtual or abstract method.
[Link]() → Explicitly calls the parent's version. Lets you reuse parent code + add your own.
Player[] array → Array of base type. Can hold any subclass (Batsman, Bowler, AllRounder) because all inherit Player.
foreach polymorphism → [Link]() calls the ACTUAL type's method automatically at runtime.
=> expression body → Shorthand for single-line methods. => BattingAverage > 50 means { return BattingAverage > 50; }
&& → AND — both conditions must be true. Runs>1000 && Wickets>50 both need to pass.

You might also like