/*
A Programmer's Introduction to C# (Second Edition)
by Eric Gunnerson
Publisher: Apress L.P.
ISBN: 1-893115-62-3
*/
// 30 - Execution-Time Code GenerationLoading AssembliesMaking it Dynamic
// copyright 2000 Eric Gunnerson
// file=LogAddInToFile.cs
// compile with: csc /r:..logdriver.dll /target:library logaddintofile.cs
using System;
using System.Collections;
using System.IO;
public class LogAddInToFile: ILogger
{
StreamWriter streamWriter;
public LogAddInToFile()
{
streamWriter = File.CreateText(@"logger.log");
streamWriter.AutoFlush = true;
}
public void Log(string message)
{
streamWriter.WriteLine(message);
}
}
//=============================================================
// 30 - Execution-Time Code GenerationLoading Assemblies
// copyright 2000 Eric Gunnerson
// file=LogDriver.cs
// compile with: csc /target:library LogDriver.cs
using System;
using System.Collections;
public interface ILogger
{
void Log(string message);
}
public class LogDriver
{
ArrayList loggers = new ArrayList();
public LogDriver()
{
}
public void AddLogger(ILogger logger)
{
loggers.Add(logger);
}
public void Log(string message)
{
foreach (ILogger logger in loggers)
{
logger.Log(message);
}
}
}
public class LogConsole: ILogger
{
public void Log(string message)
{
Console.WriteLine(message);
}
}
Language Basics
File to be used as a library assembly 2
/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
// Circle.cs -- File to be used as a library assembly
//
// Compile this file with the following command line:
// C:>csc /t:module Circle.cs
using System;
namespace nsCircle
{
// A structure to define a Cartesian point.
public struct POINT
{
public POINT (int x, int y)
{
cx = x;
cy = y;
}
public int cx;
public int cy;
public override string ToString()
{
return (String.Format ("(" + cx + ", " + cy + ")"));
}
}
public class clsCircle
{
// Two constructors to define the circle.
public clsCircle (double radius, POINT center)
{
m_Center = center;
m_Radius = radius;
}
public clsCircle (double radius, int cx, int cy)
{
m_Center.cx = cx;
m_Center.cy = cy;
m_Radius = radius;
}
public clsCircle ()
{
m_Center.cx = 0;
m_Center.cy = 0;
m_Radius = 0;
}
public double Radius
{
get {return (m_Radius);}
set {m_Radius = value;}
}
public POINT Center
{
get {return (m_Center);}
set {m_Center = value;}
}
// Fields to contain circle data.
POINT m_Center;
private double m_Radius;
// Constants to make life easier
private const double pi = 3.14159;
private const double radian = 57.29578;
// Return the area of the circle
public double Area
{
get {return (m_Radius * m_Radius * pi);}
}
// Return the diameter of the circle
public double Diameter
{
get {return (2 * m_Radius);}
}
// Return the coordinates of a point on the circle at a given angle.
public POINT PointOnCircle (double degrees)
{
POINT pt;
double fAngle = degrees / radian;
// Compute the x position of the point
pt.cx = (int)((double) m_Radius * Math.Cos (fAngle) + 0.5);
// Compute the y position of the point
pt.cy = (int)((double) m_Radius * Math.Sin (fAngle) + 0.5);
return (pt);
}
// Return the area of a slice determined by a given angle.
public double AreaOfSlice (double degrees)
{
double fAngle = degrees / 57.29578;
return (Area * fAngle / (2 * pi));
}
}
}
// Geom.cs -- Demonstrates using an assembly.
//
// Build this program and the Circle assembly using
// the following command sequence:
// C:>csc /t:module Circle.cs
// C:>sn -k Circle.snk
// C:>al /keyfile:Circle.snk /version:1.0.0.0 /out:Circle.dll Circle.NetModule
// C:>gacutil /i Circle.dll
// C:>csc /r:circle.dll Geom.cs
//
using System;
using nsCircle;
namespace nsGeometry
{
class clsMain
{
static public void Main ()
{
double angle = 32.6;
// Create an instance of the circle class.
clsCircle circle = new clsCircle (420, 0, 0);
// Get the point on the circle at the angle.
POINT pt = circle.PointOnCircle (angle);
// Show the total area of the circle.
Console.WriteLine ("The area of the circle is " + circle.Area);
// Show the point.
Console.WriteLine ("The point on the circle is at " + pt);
// Show the area of the slice between 0 degrees and the angle.
Console.WriteLine ("The area of the slice is " +
circle.AreaOfSlice (angle));
}
}
}
File to be used as a library assembly
/*
C# Programming Tips & Techniques
by Charles Wright, Kris Jamsa
Publisher: Osborne/McGraw-Hill (December 28, 2001)
ISBN: 0072193794
*/
// Circle.cs -- File to be used as a library assembly
//
// Compile this file with the following command line:
// C:>csc /t:library Circle.cs
using System;
namespace nsCircle
{
// A structure to define a Cartesian point.
public struct POINT
{
public POINT (int x, int y)
{
cx = x;
cy = y;
}
public int cx;
public int cy;
public override string ToString()
{
return (String.Format ("(" + cx + ", " + cy + ")"));
}
}
public class clsCircle
{
// Two constructors to define the circle.
public clsCircle (double radius, POINT center)
{
m_Center = center;
m_Radius = radius;
}
public clsCircle (double radius, int cx, int cy)
{
m_Center.cx = cx;
m_Center.cy = cy;
m_Radius = radius;
}
public clsCircle ()
{
m_Center.cx = 0;
m_Center.cy = 0;
m_Radius = 0;
}
public double Radius
{
get {return (m_Radius);}
set {m_Radius = value;}
}
public POINT Center
{
get {return (m_Center);}
set {m_Center = value;}
}
// Fields to contain circle data.
POINT m_Center;
private double m_Radius;
// Constants to make life easier
private const double pi = 3.14159;
private const double radian = 57.29578;
// Return the area of the circle
public double Area
{
get {return (m_Radius * m_Radius * pi);}
}
// Return the diameter of the circle
public double Diameter
{
get {return (2 * m_Radius);}
}
// Return the coordinates of a point on the circle at a given angle.
public POINT PointOnCircle (double degrees)
{
POINT pt;
double fAngle = degrees / radian;
// Compute the x position of the point
pt.cx = (int)((double) m_Radius * Math.Cos (fAngle) + 0.5);
// Compute the y position of the point
pt.cy = (int)((double) m_Radius * Math.Sin (fAngle) + 0.5);
return (pt);
}
// Return the area of a slice determined by a given angle.
public double AreaOfSlice (double degrees)
{
double fAngle = degrees / 57.29578;
return (Area * fAngle / (2 * pi));
}
}
}
// Geom.cs -- Demonstrates using an assembly.
//
// Compile this program with the following command line:
// C:>csc /r:circle.dll Geom.cs
using System;
using nsCircle;
namespace nsGeometry
{
class clsMain
{
static public void Main ()
{
double angle = 32.6;
// Create an instance of the circle class.
clsCircle circle = new clsCircle (420, 0, 0);
// Get the point on the circle at the angle.
POINT pt = circle.PointOnCircle (angle);
// Show the total area of the circle.
Console.WriteLine ("The area of the circle is " + circle.Area);
// Show the point.
Console.WriteLine ("The point on the circle is at " + pt);
// Show the area of the slice between 0 degrees and the angle.
Console.WriteLine ("The area of the slice is " +
circle.AreaOfSlice (angle));
}
}
}
CreateDelegate and DynamicInvoke
using System;
using System.Reflection;
delegate void theDelegate(int arga, int argb);
class MyClass {
public void MethodA(int arga, int argb) {
Console.WriteLine("MyClass.MethodA called: {0} {1}", arga, argb);
}
}
class Starter {
static void Main() {
Type tObj = typeof(System.MulticastDelegate);
MyClass obj = new MyClass();
Delegate del = Delegate.CreateDelegate(typeof(theDelegate), obj,"MethodA");
del.DynamicInvoke(new object[] { 1, 2 });
}
}
Combining delegates Multiple delegates are combined using the Combine method, the plus operator (+), or the += assignment operator.
using System;
public delegate void DelegateClass();
public class Starter {
public static void Main() {
DelegateClass del = MethodA;
del += MethodB;
del();
}
public static void MethodA() {
Console.WriteLine("MethodA...");
}
public static void MethodB() {
Console.WriteLine("MethodB...");
}
}
Lifetime of outer variables is aligned with the delegate
using System;
public delegate void DelegateClass(out int var);
public class Starter {
public static void Main() {
DelegateClass del = MethodA();
int var;
del(out var);
del(out var);
del(out var);
Console.WriteLine(var);
}
public static DelegateClass MethodA() {
int increment = 0;
return delegate(out int var) {
var = ++increment;
};
}
}
The publisher/subscriber relationship is a one-to-many relationship.
using System;
class Publisher {
public event EventHandler MyEvent;
}
public class Subscriber {
public static void Handler(object obj, EventArgs args) {
}
public static void Main() {
Publisher pub = new Publisher();
pub.MyEvent += Handler;
// other processing
}
}