3.4 C#的委托
在开发的各种系统中,在程序设计上是如何处理事件的触发问题呢?C++中使用函数指针来处理回调函数,但是这样的做法有巨大的副作用。而在C#中使用委托来封装事件处理函数的指针,并且使用委托来定义对象触发的事件。 在C#中如何实现一个委托呢?具体步骤如下所述。 (1)声明一个delegate对象,它和要定义的一系列触发的方法有相同的参数和返回类型。具体申请代码如下: Public delegate void InviteEventHandler(string name); (2)必须先实例化委托,创建一个delegate对象,然后把要委托的方法绑定到这个对象上。 (3)使用委托。在前面对象绑定了委托的方法后,我们只需要触发这个对象委托的事件,就会调用对应的委托方法了。 具体的示例代码如下:
Class Program
{
//定义委托声明的方法
delegate int TestDelegate(object i_object);
//定义委托的对象
static event TestDelegate m_myevent;
//程序运行的入口
static void Main(string[] args)
{
//申请委托对象事件
TestDelegate m_delegate = new TestDelegate (MyWrite);
m_delegate("This is a delegate object to call the raw
function.");
//绑定委托对象
m_myevent += m_delegate;
m_myevent += new TestDelegate(MyWrite);
m_myevent +=new TestDelegate(Class1_m_myevent);
if(m_myevent!=null){
//触发添加的委托方法事件
m_myevent("This is a event funcaion on the
delegate.");
}
}
// Mywrite函数是满足前面委托对象声明的同样的函数方法
Static private int MyWrite(object i_string)
{
Console.WriteLine(i_string);
return i_string.ToString().Length;
}
// Class1_m_myevent函数是满足前面委托对象声明的同样的函数方法
private static int Class1_m_myevent(object i_object)
{
Console.WriteLine(i_object);
return 0;
}
}
通过代码测试,相信大家对委托的使用有了一定的了解,重点需要记住委托有以下特点: ·委托在概念上类似C++中的指针,但是它是类型安全的,不会出现内存泄露。 ·委托可以把方法作为参数进行传递。 ·委托用来定义函数回调的方法。 ·委托可以把委托和委托之间连接起来,比如一个事件同时响应多个方法。
3.5 C#多线程使用介绍
在我们的系统当中,由于一些资源的加载和耗时的处理会影响整个系统运行的流畅性。这个时候就需要使用多线程编程,使用更多的CPU内核进行运算。 C#在它的接口空间threading中提供了多线程开发的类和接口,能够给开发者提供非常方便的函数和方法,可以跟操作系统进行多线程的交互处理。本节将介绍常用的多线程编程方式。
Thread是C#中最常用的多线程操作方法。它提供了对线程的各种灵活操作,使用的具体步骤如下所述。 (1)使用Thread的构造函数创建一个线程的实例,它的参数里面需要给出线程运行的函数方法。 (2)使用线程的start函数来启动这个线程。 (3)设置这个线程的优先级,通过改变属性priority来提高或者降低优先级,它决定了该线程与其他线程争夺运算时间和资源上的优先级。 具体代码示例如下:
class Program
{
//声明多线程运行的方法
static void WriteY()
{
//多线程输出100次数据
for (int i = 0; i < 1000; i++)
{
Console.Write("Thread(other):" + i);
}
}
//程序运行的主入口
static void Main(string[] args)
{
//创建一个线程
Thread thread = new Thread(WriteY);
//开始一个线程
thread.Start();
//主线程执行循环输出数据
for (int i = 0; i < 1000; i++)
{
Console.Write("Thread(main):" + i);
}
Console.ReadLine();
}
}
3.6 C#的反射机制
反射机制是C#的一个高级用法,主要应用在将开发的类打包成库和程序集,分享给别人或者其他程序的模块来使用。 从广义上可以把C#的应用程序分为3个部分,如下所述。 ·程序集-Assembly:主要负责信息管理,比如模块(Module)的信息和类型(Class)。反射的概念就是一种编程方式,让程序在运行时去装载已经编译好的程序模块组件。Assembly是一个类,通过这个类可以获得运行时配件的一些信息。程序可以在动态环境下加载配件,并且在配件中查找所需要的类的信息。通过信息创建对应的类,就可以在程序开发中动态使用组件中类的实现功能。 ·Type:这是一个类,这个类可以获得其他类对象的信息,包括类的方法构造函数、属性和参数等。Type主要是用来获得信息,它不是直接去调用类的使用。 ·MethodInfo:这个类包含了反射类中方法的名称和参数等,同时提供了类方法的调用方式。下面通过示例来说明反射的一些使用方法,首先建立一个用来调用的类,具体示例代码如下:
class MyClass
{
int x;
int y;
public MyClass(int i, int j)
{
this.x = i;
this.y = j;
}
public int Sum()
{
return x + y;
}public bool IsBetween(int i)
{
if (x < i && i < y)
{
return true;
}
return false;
}
public void Set(int a, int b)
{
x = a;
y = b;
}
public void Set(double a, double b)
{
x = (int)a;
y = (int)b;
}
public void Show()
{
Console.WriteLine("x: " + x + "y:" + y);
}
}
设置C#的工程中输出库为.dll,把这个类编译出来作为一个库进行输出,然后加载这个dll文件,如图3-3所示。
在Program.cs的Main函数中编写程序,使用反射调用MyClass。
//使用Type获得类
Type t = typeof(MyClass);
//声明反射对象
MyClass reflectOb = new MyClass(10, 20);
int val;
//调用MyClass类的方法
Console.WriteLine("Invoke methods in " + t.Name);
Console.WriteLine();
MethodInfo[] mi = t.GetMethods();
//调用每个方法
foreach (MethodInfo m in mi){
//获得方法参数
//下面的方法就是调用各种反射里的方法
ParameterInfo[] pi = m.GetParameters();
if(m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].Paramete
rType
==typeof(int))
{
// 方法的某些重载要使用的区域、大小写和排序规则
object[] obj = new object[2];
obj[0] = 9;
obj[1] = 18;
m.Invoke(reflectOb, obj);
}
elseif(m.Name.Equals("Set",StringComparison.Ordinal)&&pi[0].
ParameterType==typeof(double))
{
object[] obj = new object[2];
obj[0] = 1.12;
obj[1] = 23.4;
m.Invoke(reflectOb, obj);
}
else if (m.Name.Equals("Sum",StringComparison.Ordinal))
{
val = (int)m.Invoke(reflectOb, null);
Console.WriteLine("Sum is : " + val);
}
else if (m.Name.Equals("IsBetween",
StringComparison.Ordinal))
{
object[] obj = new object[1];
obj[0] = 14;
if ((bool)m.Invoke(reflectOb, obj))
{
Console.WriteLine("14 is between x and y");
}
}
else if (m.Name.Equals("Show",StringComparison.Ordinal))
{
m.Invoke(reflectOb,null);
}
}
3.7 Unity中使用泛型
C#作为Unity开发的主要语言,在Unity中也有一些高级用法。泛型就是经常在Unity中使用的一种高级用法。它提供了一个模板,让程序开发在运行编译的时候再决定具体的数据类型。泛型提供了一种优雅并且高效率的编程方法,它不仅提高了代码的重用性,还能让开发人员编写更加通用的解决方案。 本节将以Unity获取组件的方式演示Unity中使用最多的一种泛型方法,具体代码如下:
//unity3D中使用最多的泛型方法应该是GetCompent
//T就是占位符,当调用这个方法时要告诉编译器,这个T的具体类型
//另外,T只是一个标识,完全可以用其他代替,如K,MyType等,这只是使用习惯
//GameObject是Unity中任意物体对象的类
GameObject player;
//Animation是Unity中动画对象的类
Animator animator;
//Start是Unity脚本程序中的一个固定函数,脚本启动的时候都会调用这个函数
void Start()
{
//在场景中找到名为MyPlayer的物体,如找到了为player的GameObject对象
赋值
player = GameObject.Find("MyPlayer");
//获取该物体上的Animator组件,这里使用了
获取到了组
件上绑定的Animatior类组件
animator = player.GetComponent
//对于使用AddComponent
需要了解的
就是:我们想要的具体的组件类型
//对于泛型方法来说,泛型的作用就是占位和约束
}
相关阅读
发表评论