All the components you put to your form are comprised by the form. They become private members of the form.
System.Windows.Forms.Form inherits :
- Object
- MarshalByRefObject
- Component
- Control
- ScrollableControl
- ContainerControl
- Form
MarshalByRefObject
garantees that the object of this type is to be called only by
reference.
Component
Some practically not interesting stuff.
Control
comprises the following properties:
- Top, Left, Bottom, Right, Bounds, ClientRectangle, Height, Width
- Created, Disposed, Enabled, Focused, Visible
- HWND Handle
- Keys ModifierKeys
- MouseButtons MouseButtons
- Text
- AllowDrop
- ContextMenu
- Dock
- Opacity
- Region
methods:
- Hide(), Show(), Invalidate(), Refresh()
- OnXXXX()
- SetBounds(), SetLocation(), SetClientArea()
-
- MouseButtons MouseButtons
- Text
events:
- Click, DoubleClick, MouseEnter, MouseLeave, MouseDown, MouseUp, MouseMove, MouseHover, MouseWheel
- KeyPress, KeyUp, KeyDown
ScrollableControl
This class is needed to provide horizontal and vertical scroll ability.
Properties (are to be places into form constructor):
- bool AutoScroll
- System.Drawing.Size AutoScrollMinSize
ContainerControl
The most important properties and methods:
- ActiveControl
- ParentForm
- ProcessTabKey()
Form
Some important properties:
- AcceptButton, CancelButton
- bool MaximizeBox, MinimizeBox
- FormStartPosition StartPosition
- FormWindowState WindowState
and some methods:
- Activate()
- Close()
- CenterToScreen()
- LayoutMDI LayoutMDI()
- OnResize()
- ShowDialog()
and some events:
- Activate
- Close, Closing
- MDIChildActive
Assembly .NET
Manifest [assembly metadata: entire list of dependences to another assemblies, version of the assembly(identifier: informational version + compatibility version; compatibility version: W.X.Y.Z; W is major, X is minor, Y is build number, Z is revision number )] |
Type metadata [includes info about whether a type is public or private i.e. could be used outside or hidden for outer usage] |
Intermediate Language code [it's somewhat like assembler code but not native, i.e. assembler for every type of processor where the IL code to native code converter is written] |
Example: single-file assembly using
using System;
using System.Collections.Generic;
using System.Text;
namespace SeasonLibrary
{
public enum SeasonState
{
Winter,
Spring,
Summer,
Autumn
}
public interface Season
{
void perform();
}
public class Winter: Season
{
public void perform()
{
Console.WriteLine( "Snowing..." );
}
}
public class Spring : Season
{
public void perform()
{
Console.WriteLine("Getting warm...");
}
}
public class Summer : Season
{
public void perform()
{
Console.WriteLine("Very very hot...");
}
}
public class Autumn : Season
{
public void perform()
{
Console.WriteLine("Everything is yellow and red...");
}
}
}
// CLIENT APPLICATION, HAVING REFERENCE TO THE LIBRARY
using System;
using System.Collections.Generic;
using System.Text;
namespace SeasonApp
{
class Program
{
static void Main(string[] args)
{
SeasonLibrary.Season[] sa = new SeasonLibrary.Season[4];
sa[0] = new SeasonLibrary.Winter();
sa[1] = new SeasonLibrary.Spring();
sa[2] = new SeasonLibrary.Summer();
sa[3] = new SeasonLibrary.Autumn();
for (int i = 0; i < sa.Length; ++i)
sa[i].perform();
}
}
}
//OUTPUT
//Snowing...
//Getting warm...
//Very very hot...
//Everything is yellow and red...
ICloneable
If you wanna have a
deep copy but not a
shallow copy which is just one more link to the same object in the memo, you should derive your class from the
IClonable interface and realize the
IClonable.Clone() method. The simpliest way is just return new object of this one:
class X: IClonable
{
public X(params)
{
//...
}
public object Clone()
{
return new X(params);
}
}
The only thing you should know before you do that is that you didn't derive your class from some another class allready supporting this IClonable interface!
IComparable
Derive your class from
IComparable and realize
int CompareTo(object o); method. And at the same time returning value should be:
- <0 if your object is less than o;
- =0 if your object equals to o;
- >0 if your object is more than o.
As you've allready understood, the way you compare these two objects is entirely your business.
Indexer
Is a little bit modified
property with the name
this and square brackets
[int pos] and some returning type (no matter whichever):
Indexer example
namespace Indexer
{
class Bitch
{
string name;
public Bitch(string name)
{
this.name = name;
}
public string Name
{
get {
return this.name;
}
}
}
class Bitches
{
Bitch[] bs = new Bitch[3];
public Bitches()
{
bs[0] = new Bitch("Suko");
bs[1] = new Bitch("Padlo");
bs[2] = new Bitch("Uyebanishe");
}
public Bitch this[int pos]
{
get
{
Console.WriteLine( "get method" );
if (pos < 3 && pos >= 0)
return bs[pos];
throw new IndexOutOfRangeException("get: Out of mother fucking range, dude");
}
set
{
Console.WriteLine( "set method" );
if (pos < 3 && pos >= 0)
bs[pos] = value;
throw new IndexOutOfRangeException("set: Out of mother fucking range, dude");
}
}
}
class Program
{
static void Main(string[] args)
{
Bitches b = new Bitches();
Console.WriteLine("{0}", b[0].Name);
Console.WriteLine("{0}", b[1].Name);
Console.WriteLine("{0}", b[2].Name);
}
}
}
//OUTPUT
//get method
//Suko
//get method
//Padlo
//get method
//Uyebanishe
Classical inheritance
is a relationship
is-a. And there is another way to reuse written classes inside your classes having name
has-a.
Internal & public classes/structures/enumerations/etc
You can declare your class either
internal or
public to close you class inside the
namespace or to make it usable outside the
namespace.
Constructors
If you made at least one constructor for a class then the
default constructor is not generated automatically. You should write it by yourself.
Another terms
- - sealed means that you can't derive a new class from the sealed one.
- - Nested class is a class, declared inside another one.
- - virtual and override are needed for polymorphism: to declare method to be overriden in derived class. virtual can not be private.
- - abstract prohibits creation of class which is declared as abstract. But you may derive some class from this one and make instance of it. Also, abstract means that the method which is declared as abstract MUST be overriden in derivded class. abstract can not be private.
- - new is needed to brake the virtual link between the same called methods in parent and derived classes. Casting object to lower class (parent class) you can call version of the method corresponding to parent method's version.
Class method's version control example
abstract class A
{
public A()
{
Console.WriteLine( "{0}: A ctor", this.ToString() );
}
public abstract void draw() ;
}
class B: A
{
public B()//: base()
{
Console.WriteLine("{0}: B ctor", this.ToString());
}
public override void draw()
{
Console.WriteLine( "B: draw()" );
}
}
class C: A
{
public C()//: base()
{
Console.WriteLine("{0}: C ctor", this.ToString());
}
public override void draw()
{
Console.WriteLine( "C: draw()" );
}
}
class D: C
{
public D()//: base()
{
Console.WriteLine("{0}: D ctor", this.ToString());
}
public new void draw()
{
Console.WriteLine( "D: draw()" );
}
}
//....
public static void Main( string[] argv )
{
D d = new D();
C c = (C)d;
A a = (A)d;
c.draw();
d.draw();
a.draw();
}
// OUTPUT
BaseTest.D: A ctor
BaseTest.D: C ctor
BaseTest.D: D ctor
C: draw()
D: draw()
C: draw()
If you put override instead of new in D.draw() method's declaration, you'll get:
BaseTest.D: A ctor
BaseTest.D: C ctor
BaseTest.D: D ctor
C: draw()
C: draw()
C: draw()
Interface
- - no constructors;
- - no access modifiers;
- - no definition and fields (you can't even write empty brackets {} after method name!);
- - explicit interface definition makes different realization for methods with the same names. But if you've derived your class from abstract class and interface with the same method names - you'll have got the only one realization in your end class for both abstract class and interface.
Example: implicit method definition
abstract class Shape
{
public abstract void Draw();
}
interface IDrawable
{
void Draw();
}
class Circle : Shape, IDrawable
{
public override void Draw()
{
Console.WriteLine( "The only one realization in fact" );
}
}
class Program
{
static void Main(string[] args)
{
Circle cir = new Circle();
cir.Draw();
((IDrawable)cir).Draw();
((Shape)cir).Draw();
}
}
//OUTPUT
The only one realization in fact
The only one realization in fact
The only one realization in fact
But if you wanna derive your class from two different interfaces with the same called methods and then use both those methods you just define explicitly both realizations for both interfaces in the end class:
Example: explicit method definition
interface PPPConnection
{
void Connect();
}
interface WIFIConnection
{
void Connect();
}
// Explicit interface definition
class Connection : PPPConnection, WIFIConnection
{
void PPPConnection.Connect()
{
Console.WriteLine( "Making a ppp connection" );
}
void WIFIConnection.Connect()
{
Console.WriteLine( "making a WiFi connection" );
}
}
class Program
{
static void Main(string[] args)
{
Connection c = new Connection();
((PPPConnection)c).Connect();
((WIFIConnection)c).Connect();
}
}
//OUTPUT
Making a ppp connection
Making a WiFi connection
Enumerable class
To make your class working in
foreach() operator you should do the following:
- - derive your class from IEnumerable and IEnumerator. When you're declaring new enumerable class write the full name of IEnumerable and IEnumerator using the prefix: System.Collections.IEnumerable and System.Collections.IEnumerator (otherwise the compiler will require to write the parameter type);
- - add real definition of the following 4 methods to your class:
bool MoveNext(); //Move inner pointer of object set one position futher.
object Current(); //Gives current object in the set.
void Reset(); //Set position to the first object in the set.
public IEnumerator GetEnumerator()
Enumerable class example: cars
using System;
using System.Collections.Generic;
using System.Text;
namespace EnumerableClass
{
class Car
{
string name;
public Car()
{
name = "Unnamed";
init();
}
public Car(string name)
{
this.name = name;
init();
}
private void init()
{
Car.id++;
}
public static int getId()
{
return Car.id;
}
public string Name
{
get { return name; }
}
public static int id = 0;
}
class Cars : System.Collections.IEnumerable, System.Collections.IEnumerator
{
private Car[] cars;
int pos = -1;
public Cars()
{
cars = new Car[6];
cars[0] = new Car( "Betsy" );
cars[1] = new Car( "Lindsay" );
cars[2] = new Car( "Diana" );
cars[3] = new Car( "Johny" );
cars[4] = new Car( "Dana" );
cars[5] = new Car( "Crystol" );
}
public System.Collections.IEnumerator GetEnumerator()
{
return (System.Collections.IEnumerator)this;
}
public object Current
{
get {
return cars[pos];
}
}
public void Reset()
{
pos = 0;
}
public bool MoveNext()
{
if (pos + 1 == cars.Length)
return false;
++pos;
return true;
}
}
class Program
{
static void Main(string[] args)
{
Cars cs = new Cars();
foreach (Car car in cs)
{
Console.WriteLine( "Car {0} ", car.Name );
}
}
}
}
// OUTPUT
Car Betsy
Car Lindsay
Car Diana
Car Johny
Car Dana
Car Crystol