
TypeA T1 = new TypeA();
TypeB T2 = new TypeB();
// Not Binding: Reference from Parent --> object from Parent- ุฅูู ุฃุนู ู Reference ูุดุงูุฑ ุนูู Child ููู class ุงููู ุจุนู ู ู ูู Reference
- ุจู ุนูู ุฅูู ุฃูุฏุฑ ุจุงูู Reference ููู Class ุฃุดุงูุฑ ุนูู ููุณ ุงูู Class ุฃู Child ูู
// Parent Child
TypeA T1 = new TypeB(1, 2);
// Reference from Parent --> Object from Child- ู ุด ุจูุดูู ุบูุฑ ุงูุฌุฒุก ุงููู ุงูุฅุจู ูุงุฑุซู ู ู ุงูุฃุจ ุจุณ ุบูุฑ ูุฏุง ู ุจูุดููุด
- ูู ุนุจุงุฑุฉ ุนู Reference Type
- ุงูู Reference ุงููู ูู ุงูุนููุงู ููุฑูุญ ูู ุงูู Stack ูุงูู Object ููุณู ุฃู ุงูููู ุฉ ูู ุงูู Heap
TypeA T1 = new TypeB();
// Reference Object
// Address Value
// Stack HeapOverride
- ุนุฑููุง ุงู ููู ุทุฑููุชูู ููู Override ููุง Override ุงูู Static Binding (Early Binding):
- ูู ุนู ูุช override ุนู ุทุฑูู new ููููุฐ ุฃูู Function ุนูุฏู ุจุชุงุน ุงูู Parent ู ุด ููุดูู ุงูู Override ุงูุฌุฏูุฏุฉ ูููุนุชุจุฑ ุฏู Function ุฌุฏูุฏุฉ ุจูููุฑุฏ ุจููุง ุงูู Child
- Compiler will bind function call based on Reference Type NOT Object Type at compilation Time ุงูู Dynamic Binding:
- ุฅูู ุง ูู ุจููู ุฉ override ููููุฐ ุงููู ุงูุช ุนู ูุชู ูุงูุฃุฎุฑ ูููููุฐูุง (ุจุชุงุน ุงูุฅุจู)
- CLR will Bind Function Call based on Object Type NOT Reference Type at Run Time
Not Binding
ู ุซุงู:
- ูู ุนูุฏู ููุจ ุฃูุฏุฑ ุฃููู ุนููู ุฅูู ุญููุงู
- ุจุณ ู ุด ูู ุญููุงู ููุฏุฑ ุฃููู ุนููู ุงูู ููุจ
- ุนุดุงู ูุฏุง ููุง ุจูุณุชุฎุฏู Type Casting in CSharp ูู ุงูุญุงูุฉ ุงููู ุฒู ุฏู
// Dog = Animal // ู
ูุฏุฑุด
// Dog = (Dog) Animal // ุงูุญููุงู ุฏุง ุจูุนุฏู ุงูู ููุจ
object O1 = 3;
// int x = O1; // ERROR
// Cause
// O1 = "Ahmed"; // Object can be anything
int x = (int) O1; // ุจูุนุฏู ููุจูุง ุงูุชุฌุฑ
// (int): built-in casting operator
TypeA T1;
T1 = new TypeA(1);
T1 = new TypeB(1, 2); // Child -> Binding
TypeB = T2;
T2 = new TypeA(); // ERROR
T2 = T1; // ERROR
T2 = (TypeB) T1;
// ุจูุนุฏู ุงูู ููุจูุง ุงูุฅุจู ุฏุง ุจุงูุฐุงุช ูุฃู ูู ุนูุฏู ุฃุจูุงุก ูุชูุฑ
// This is NOT Binding
// (TypeB): We need to make this casting operatorุงูู ูุถูุน ุฏุง ู ุฑุชุจุท ุจุงูู Cs Casting Operator ุดููุฉ ูุฃู ูุงุฒู ุฃุนู ู Casting Operator ููุฅุจู ูู ุง ุจุฎููู ูุงุฎุฏ Object ุฃุจ ูุฃู ููู ุญุงุฌุฉ ุฒูุงุฏุฉ ุจุชุจูุง ู ูุฌูุฏุฉ ู ุซุงู: ุงูุฃุจ ุนูุฏู A ูุงูุฅุจู ูุฑุซู ู ูู ููู ุงู ุฒูุฏ B ุฃูุง ุฏูููุชู ูุนู ู ุงุจู ู ู Object ุฃุจ ุจุณ ุงูุฅุจู ุงูู ูุฑูุถ ูุนุฑู ุงูุญุงุฌุฉ ุงูุฒูุงุฏุฉ ุจุชุงุนุชู ูุชุจูุง ุจุฅูู
Example
Example 1
internal class Employee
{
public int id { get; set; }
public string name { get; set; }
public void MyFunc01()
{
Console.WriteLine("I am Employee");
}
public virtual void MyFunc02()
{
Console.WriteLine($"ID: {id}, Name: {name}");
}
}
class FullTimeEmployee : Employee
{
public int salary { get; set; }
public new void MyFunc01()
{
Console.WriteLine("I am FullTime Employee");
}
public override void MyFunc02()
{
Console.WriteLine($"ID: {id}, Name: {name}, Salary: {salary}");
}
}
class PartTimeEmployee : Employee
{
public int HoursOfWork { get; set; }
public new void MyFunc01()
{
Console.WriteLine("I am PartTime Employee");
}
public override void MyFunc02()
{
Console.WriteLine($"ID: {id}, Name: {name}, HoursOfWork: {HoursOfWork}");
}
}
// We will try to make function for them
public void ProcessEmployee(FullTimeEmployee emp)
{
emp.MyFunc01();
emp.MyFunc02();
}
public void ProcessEmployee(PartTimeEmployee emp)
{
emp.MyFunc01();
emp.MyFunc02();
}
// ุฏุง ู
ุด ุงููุฑููุฏููุฌ ุฏุง ุนูุ ูุฃู ุงูุฅุชููู ููุณ ุงูุจูุฏู
// The solution here is BINDING
public void ProcessEmployee(Employee emp)
{
emp.MyFunc01();
emp.MyFunc02();
}Example 2
- ุฎุฏ ุจุงูู ู ู ุงูู ููููุฐ ุขุฎุฑ Override ูุงู ู ูุฌูุฏ ูู ุงุณุชุฎุฏู ุช ุงูู Static Binding
class TypeA
{
public int A { get; set; }
public TypeA(int _A=0) { A = _A; }
public void StaticallyBindedShow ()
{
Console.WriteLine("I am Base");
}
///Dynamically Binded
internal virtual void DynShow () ///non Private Virtual Method
{
Console.WriteLine($"Base {A}");
}
}
class TypeB:TypeA
{
public int B { get; set; }
public TypeB(int _A =0 , int _B=0):base(_A)
{
B = _B;
}
internal override void DynShow()
{
Console.WriteLine($"Derived {A} {B}");
}
public new void StaticallyBindedShow() {
Console.WriteLine("I am Derived");
}
}
class TypeC : TypeB
{
public int C { get; set; }
public TypeC(int _a=0 , int _b=0 , int _c=0):base(_a , _b)
{
C = _c;
}
internal override void DynShow()
{
Console.WriteLine($"Type C {A} {B} {C}");
}
}
class TypeD : TypeC
{
//internal new void DynShow()
/// new statically binded impelementation
/// new dynamically binded impelementation
internal new virtual void DynShow()
{
Console.WriteLine("Type D");
}
}
class TypeE: TypeD
{
///override on TypeD Implementation
internal override void DynShow()
{
Console.WriteLine("Type E");
}
}
class program
{
static void Main(string[] args)
{
TypeA BaseRef = new TypeA(1);
BaseRef.StaticallyBindedShow(); ///Base
BaseRef.DynShow(); ///Base
TypeB DerivedRef = new TypeB(2, 3);
DerivedRef.StaticallyBindedShow(); ///Derived
DerivedRef.DynShow(); ///Derived
BaseRef = new TypeB(4, 5);
///Ref to Base = Derived Object
//BaseRef.A = 6;
BaseRef.StaticallyBindedShow();///Base
///Statically Binded methods (non virtual)
//Compiler Bind Call based in Refrence Type not Object Type
BaseRef.DynShow();///Derived
///Dynamically Binded Method , CLR will bind Function
//Call based on Object Type in Runtime
BaseRef = new TypeC(6, 7, 8);
DerivedRef = new TypeC(9, 10, 11);
BaseRef.DynShow(); ///TypeC
DerivedRef.DynShow(); ///TypeC
BaseRef = new TypeD();
BaseRef.DynShow(); ///TypeC
TypeD RefD = new TypeD();
RefD.DynShow(); ///TypeD
}
}