c# Basics

Keywords: C#

1. Polymorphism

1. abstract class

1. You cannot create an instance of an abstract class.
2. You cannot declare an abstract method outside an abstract class.
3. By placing the keyword sealed in front of the class definition, you can declare the class as a sealed class. When a class is declared sealed, it cannot be inherited. Abstract classes cannot be declared sealed.

using System;
namespace PolymorphismApplication
{
   abstract class Shape
   {
       abstract public int area();
   }
   class Rectangle:  Shape
   {
      private int length;
      private int width;
      public Rectangle( int a=0, int b=0)
      {
         length = a;
         width = b;
      }
      public override int area ()
      {
         Console.WriteLine("Rectangle Area of class:");
         return (width * length);
      }
   }

   class RectangleTester
   {
      static void Main(string[] args)
      {
         Rectangle r = new Rectangle(10, 7);
         double a = r.area();
         Console.WriteLine("the measure of area: {0}",a);
         Console.ReadKey();
      }
   }
}

2. Virtual function

using System;
using System.Collections.Generic;

public class Shape
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    // Virtual method
    public virtual void Draw()
    {
        Console.WriteLine("Execute the drawing task of the base class");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a circle");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("draw a rectangle ");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("Draw a triangle");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // Create a list < Shape > object and add Circle, Triangle, and Rectangle to it
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // Use the foreach loop to loop through the derived classes of the list and call the Draw method on each Shape object in it
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("Press any key to exit.");
        Console.ReadKey();
    }

}

2. Operator overloading

using System;

namespace OperatorOvlApplication
{
   class Box
   {
      private double length;      // length
      private double breadth;     // width
      private double height;      // height

      public double getVolume()
      {
         return length * breadth * height;
      }
      public void setLength( double len )
      {
         length = len;
      }

      public void setBreadth( double bre )
      {
         breadth = bre;
      }

      public void setHeight( double hei )
      {
         height = hei;
      }
      // Overload the + operator to add two Box objects
      public static Box operator+ (Box b, Box c)
      {
         Box box = new Box();
         box.length = b.length + c.length;
         box.breadth = b.breadth + c.breadth;
         box.height = b.height + c.height;
         return box;
      }

   }

   class Tester
   {
      static void Main(string[] args)
      {
         Box Box1 = new Box();         // Declare Box1, type Box
         Box Box2 = new Box();         // Declare Box2, type Box
         Box Box3 = new Box();         // Declare Box3, type Box
         double volume = 0.0;          // volume

         // Box1 details
         Box1.setLength(6.0);
         Box1.setBreadth(7.0);
         Box1.setHeight(5.0);

         // Box2 details
         Box2.setLength(12.0);
         Box2.setBreadth(13.0);
         Box2.setHeight(10.0);

         // Volume of Box1
         volume = Box1.getVolume();
         Console.WriteLine("Box1 Volume of: {0}", volume);

         // Volume of Box2
         volume = Box2.getVolume();
         Console.WriteLine("Box2 Volume of: {0}", volume);

         // Add two objects
         Box3 = Box1 + Box2;

         // Volume of Box3
         volume = Box3.getVolume();
         Console.WriteLine("Box3 Volume of: {0}", volume);
         Console.ReadKey();
      }
   }
}

3. Interface and interface inheritance

using System;

interface IParentInterface
{
    void ParentInterfaceMethod();
}

interface IMyInterface : IParentInterface
{
    void MethodToImplement();
}

class InterfaceImplementer : IMyInterface
{
    static void Main()
    {
        InterfaceImplementer iImp = new InterfaceImplementer();
        iImp.MethodToImplement();
        iImp.ParentInterfaceMethod();
    }

    public void MethodToImplement()
    {
        Console.WriteLine("MethodToImplement() called.");
    }

    public void ParentInterfaceMethod()
    {
        Console.WriteLine("ParentInterfaceMethod() called.");
    }
}

4. Namespace

using System;
using first_space;
using second_space;

namespace first_space
{
   class abc
   {
      public void func()
      {
         Console.WriteLine("Inside first_space");
      }
   }
}
namespace second_space
{
   class efg
   {
      public void func()
      {
         Console.WriteLine("Inside second_space");
      }
   }
}  
class TestClass
{
   static void Main(string[] args)
   {
      abc fc = new abc();
      efg sc = new efg();
      fc.func();
      sc.func();
      Console.ReadKey();
   }
}

5. Characteristics

1. The parameter validon specifies the language element in which the feature can be placed. It is a combination of the values of the enumerator AttributeTargets. The default value is AttributeTargets.All.
2. The parameter AllowMultiple (optional) provides a Boolean value for the AllowMultiple property of the feature. If true, the feature is versatile. The default value is false (single use).
3. The parameter Inherited (optional) provides a Boolean value for the Inherited property of the property. If true, the attribute can be Inherited by derived classes. The default value is false (not Inherited).

[AttributeUsage(
   validon,
   AllowMultiple=allowmultiple,
   Inherited=inherited
)]

1.Obsolete

This predefined feature marks program entities that should not be used. It lets you tell the compiler to discard a specific target element. For example, when a new method is used in a class, but you still want to keep the old method in the class, you can mark it obsolete by displaying a message that the new method should be used instead of the old method.

The syntax for specifying this feature is as follows:

using System;
public class MyClass
{
   [Obsolete("Don't use OldMethod, use NewMethod instead", true)]
   static void OldMethod()
   {
      Console.WriteLine("It is the old method");
   }
   static void NewMethod()
   {
      Console.WriteLine("It is the new method");
   }
   public static void Main()
   {
      OldMethod();
   }
}

2. Create a custom Attribute
The so-called custom message is defined through AttributeUsage. Usually, it is to write a class to inherit from Attribute. Of course, the tag Attribute should also be added.

[AttributeUsage(
    AttributeTargets.Class| 
    AttributeTargets.Constructor| 
    AttributeTargets.Field| 
    AttributeTargets.Method| 
    AttributeTargets.Property| 
    AttributeTargets.Property, 
    AllowMultiple=true 
)] 
public class DebugInfo:System.Attribute{   
    //constructor   
    //field1......   
    //method......   
    //Property...... 
} 
[DebugInfo Constructor] 
class Rectangle() {   
    //[DebugInfo constructor]   
    //Method 1   
    [DebugInfo(55,"Zara Ali","19/10/2012")]   
    public double SayHello(){     
      //do somethindg;     
      //  
     } 
}

The so-called reflection is to extract the label information of classes or methods.

For example:

Rectangele rect=new Rectangle(); 
Type type=typeof(Rectangle); 
foreach(object attributes in type.GetCustomAttributes(false)) { 
    DeBugInfo dbi=(DeBugInfo)attributes; //Print dbi properties 
} ‚Äč

3.conditional

#define BUG
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Text.RegularExpressions;
using System.Threading;
using System.Diagnostics;


namespace helloworld
{
    public class Myclass
    {
        [Conditional("BUG")]
        public static void M1(string msg)
        {
            Console.WriteLine(msg);
        }
        [Conditional("deBUG")]
        public static void M2(string msg)
        {
            Console.WriteLine(msg);
        }
        [Conditional("BUG")]
        public static void M3(string msg)
        {
            Console.WriteLine(msg);
        }
        [Conditional("kk")]
        public static void M4(string msg)
        {
            Console.WriteLine(msg);
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Myclass.M1("456");
            Myclass.M2("845");
            Myclass.M3("dadasd");
            Myclass.M4("456xcvc");
            Console.WriteLine("Main thread ID is:" );
            Console.ReadKey();
        }
    }
}

If the #define BUG of the header is defined as #define kk, only the M4 method will be run.

However, note that if [] is not written, it will be executed. Therefore, when adding [] attribable, you often see that if it is added, it will be added to each method.

6. Reflection

Reflection has the following uses:

It allows you to view properties at run time( attribute)Information.
It allows you to review various types in a collection and instantiate them.
It allows you to delay binding methods and properties( property). 
It allows you to create new types at run time and then use them to perform some tasks.
Insert the code slice here

Posted by jeffgman on Wed, 29 Sep 2021 19:54:02 -0700