Classes

advertisement
FUN WITH C#
EPISODE XIII
INTERFACES STRIKE BACK
CLI Type System
All types
Value types
Reference types
(allocated in-place
[with exceptions])
(allocated on
managed heap)
Structures
Enumerations
Classes
Interfaces
(e.g. strings)
Simple types
(Int32, Int64,
Double, Boolean,
Char, …)
Nullables
User defined structures
Pointers
Arrays
Delegates
CLI Type Inheritance
pointers
System.Object
(C#: Type *)
(C# keyword: object)
interfaces
(C# keyword: interface)
System.String
(C# keyword: string)
System.Array
System.Delegate
arrays
System.MulticastDelegate
(C#: Type[] or Type[,])
System.ValueType
delegates
user-defined classes
(C# keyword: delegate)
(C# keyword: class)
simple types
System.Int32
(C# keyword: int)
System.Double
System.Int64
(C# keyword: double)
(C# keyword: long)
System.Enum
System.Boolean
(C# keyword: bool)
…
System.Nullable
(C#: Type?)
user-defined
structures
(C# keyword: struct)
enumerations
(C# keyword: enum)
Interfaces
Interface Constraints: Is It Correct?
interface I1 {
void m();
}
interface I2 {
void m();
}
class B : I1, I2 {
public void m() {
Console.WriteLine("B.m()");
}
}
class Y<T> where T : I1, I2 {
public static void m(T t) {
t.m();
}
}
class Program {
static void Main(string[] args) {
new B().m();
Y<B>.m(new B());
}
}
Implementing Generic Interfaces
interface I<T> {
void m(T x);
T m();
}
class A : I<int>, I<long> {
?
}
Implementing Generic Interfaces
interface I<T> {
void m(T x);
T m();
}
class A : I<int>, I<long> {
public void m(int x) { Console.WriteLine("int m"); }
public void m(long x) { Console.WriteLine("long m"); }
public int m() { return -1; }
long I<long>.m() { return -2; }
}
class Program {
static void Main(string[] args) {
A a = new A();
a.m(0);
a.m(0L);
// Same as a.m(0l);
((I<int>) a).m(0);
((I<long>) a).m(0);
Console.WriteLine(a.m());
Console.WriteLine(((I<long>) a).m());
}
}
Implementing Generic Interfaces
interface I<T> {
void m(T x);
T m();
}
class A : I<int>, I<long> {
public void m(int x) { Console.WriteLine("int m"); }
public void m(long x) { Console.WriteLine("long m"); }
public int m() { return -1; }
long I<long>.m() { return -2; }
}
class Program {
static void Main(string[] args) {
A a = new A();
a.m(0);
a.m(0L);
// Same as a.m(0l);
((I<int>) a).m(0);
((I<long>) a).m(0);
Console.WriteLine(a.m());
Console.WriteLine(((I<long>) a).m());
}
}
Interfaces and Value Types
IDisposable
public interface IDisposable {
void Dispose()
}
public class ObjectDisposedException : InvalidOperationException {}
Class System.Object
Topmost base class of all other classes
class Object {
protected object MemberwiseClone() {...}
public Type GetType() {...}
public virtual bool Equals (object o) {...}
public virtual string ToString() {...}
public virtual int GetHashCode() {...}
public static bool ReferenceEquals(object objA, object objB);
}
IEqualityComparer<in T>
public interface IEqualityComparer<in T> {
int GetHashCode(T obj);
bool Equals(T x, T y);
}
Used by Dictionary<T> and HashSet<T> collections.
EqualityComparer<T>.Default: a default implementation of a IEqualityComparer<T> for type T
Class System.Object
Topmost base class of all other classes
class Object {
protected object MemberwiseClone() {...}
public Type GetType() {...}
public virtual bool Equals (object o) {...}
public virtual string ToString() {...}
public virtual int GetHashCode() {...}
public static bool ReferenceEquals(object objA, object objB);
}
Sorting: IComparable and IComparer
IComparable is interface for types with order
public interface IComparable {
int CompareTo(object obj); // <0 if this < obj, 0 if this == obj, >0 if this > obj
}
public interface IComparable<in T> {
int CompareTo(T obj); // <0 if this < obj, 0 if this == obj, >0 if this > obj
}
classes implementing IComparable are
values types like Int32, Double, DateTime, …
class Enum as base class of all enumeration types
class String
IComparer is interface for the realization of compare operators
public interface IComparer {
int Compare(object x, object y); // <0 if x < y, 0 if x == y, >0 if x > y
}
public interface IComparer<in T> {
int Compare(T x, T y); // <0 if x < y, 0 if x == y, >0 if x > y
}
Custom IComparer Implementation
Creation of table of strings:
string[][] Table = {
new string[] {"John", "Dow", "programmer"},
new string[] {"Bob", "Smith", "agent"},
new string[] {"Jane", "Dow", "assistant"},
new string[] {"Jack", "Sparrow", "manager"}
};
Printing the table:
foreach (string[] Row in Table) {
Console.WriteLine(String.Join(", ", Row));
}
Custom IComparer Implementation (2)
Comparer for single table (array) column:
class ArrayComparer<T> : IComparer<T[]> where T : IComparable<T> {
private int m_Index;
public ArrayComparer(int Index) {
m_Index = Index;
}
public int Compare(T[] x, T[] y) {
return x[m_Index].CompareTo(y[m_Index]);
}
}
Printing the table:
Array.Sort(Employees, new ArrayComparer<string>(2));
foreach (string[] Row in Employees) {
Console.WriteLine(String.Join(", ", Row));
}
Bob, Smith, agent
Jane, Dow, assistant
Jack, Sparrow, manager
John, Dow, programmer
"BCL v2-friendly" Custom Classes 1/3
In order to cooperate smoothly with other BCL classes
in the framework 2.0, custom classes should:
override ToString and GetHashCode
overload == and !=
(implement ICloneable)
public interface ICloneable {
object Clone();
}
class MyClass : ICloneable {
public object Clone() { return MemberwiseClone(); }
}
"BCL v2-friendly" Custom Classes 2/3
implement IComparable and IComparable<T>
public interface IComparable {
int CompareTo(object obj); // <0: this < obj, 0: this == obj, >0: this > obj
}
public interface IComparable<T> {
int CompareTo(T obj); // <0: this < obj, 0: this == obj, >0: this > obj
}
class Fraction : IComparable, IComparable<Fraction> {
int n, d;
public int CompareTo(object obj) {
if (f == null) return 1;
if (!(obj is Fraction)) throw new ArgumentException(“Must be of Fraction type.”, “obj”);
return CompareTo((Fraction) obj);
}
public int CompareTo(Fraction f) {
if (f == null) return 1;
return n*f.d – f.n*d
}
}
"BCL v2-friendly" Custom Classes 3/3
override Equals(object) and implement IEquatable<T>
public class Object {
public virtual bool Equals(Object obj);
…
}
public interface IEquatable<T> {
bool Equals(T other);
}
class Fraction : IEquatable<Fraction> { // equal to class Fraction : object, IEquatable<Fraction>
int n, d;
public override bool Equals(object obj) {
Fraction f = obj as Fraction;
if (f == null) return false;
return Equals(f);
}
public bool Equals(Fraction f) {
return f.n == n && f.d == d;
}
}
Mé předměty o .NET a C#
NPRG035 ZS 2/2 Zk/Z “Jazyk C# a platforma .NET”
Základy jazyka, knihoven a běhového prostředí (pro kvalitní OOP), SW inženýrství
NPRG038 LS 2/2 Zk/Z “Programování pro .NET I“
Pokročilé možnosti jazyka a knihoven potřebné pro „moderní“ programování: delegáti, vlákna a
asynchronní programování, síťování, Reflection, generování kódu, enumerační metody, LINQ to Objects
NPRG057 LS 2/0 Zk “Programování pro .NET II”
„interface s okolím“: bezpečnost (.NET Security), interoperabilita s C++, unsafe kód, Python, hostování CLR
v C++, vzdálené volání objektů: Remoting, WCF, databáze, ?WF?
Od AR 2015/2016 zakončeno pouze přehledovou zkouškou bez „zápočtového“ programu
?NPRG061? LS 0/2 Z (1 kredit) “Programování uživatelských rozhraní v .NET”
„interface s uživatelem“: WinForms, WPF, ASP.NET WebForms, ASP.NET MVC, lokalizace a globalizace
aplikací, programování her a visualizačních aplikací ve 2D a 3D (např. WaveEngine, apod.)
Pilotní běh “po večerech“ v LS 2015/2016
Vypsané od AR 2016/2017 – zápočet za 1 kredit za uznaný zápočtový program z NPRG035 nebo NPRG038 s
netriviálním uživatelským rozhraním
(všechny 3 letní předměty je principiálně možné studovat paralelně jako navazující jen
na zimní NPRG035)
Download