关于delegate的问题?

qing_j09 2003-01-14 03:10:55
1.namespace的用法及含义?
2.关于delegate?
比如在一个类里面声明delegate对象==>public delegate void MyDelegate(string name)和在类外面声明delegate对象一样吗?调用上有何区别?可以用其它技术替代delegate吗?



...全文
234 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
xiajianfeng 2003-01-14
  • 打赏
  • 举报
回复
可以用其它技术替代delegate吗?

在与委托最为相似的是函数指针。然而,函数指针只能引用静态函数,而委托可以引用静态方法和实例方法。当委托引用实例方法时,委托不仅存储对方法入口点的引用,还存储对为其调用该方法的类实例的引用。与函数指针不同,委托是面向对象、类型安全并且安全的。

henryfan1 2003-01-14
  • 打赏
  • 举报
回复
委托在类内声明为公有,同在类外应该没什么差别,
不过我都是在类外声明的。
代替它,用函数指针啊,应该还有其它方法代替它的。
不过我不会:)
win32c 2003-01-14
  • 打赏
  • 举报
回复
命名空间组织在程序集中定义的对象。程序集可以包含多个命名空间,而命名空间可以包含其他命名空间。命名空间避免了使用大的对象组(如类库)时的多义性并简化了引用。

例如,Visual Studio .NET 在 System.Windows.Forms 命名空间中定义 ListBox 类。以下代码片段说明如何使用该类的完全限定名声明变量:

Dim LBox As System.Windows.Forms.ListBox
Visual Studio.NET 命名空间解决了有时被称为“命名空间污染”的问题,即在另一个库中使用类似名称妨碍了类库的开发者。这些同现有组件的冲突有时被称为“名称冲突”。

例如,如果创建一个名为 ListBox 的新类,则在项目内部不需任何限定即可使用它。但是,如果不想在同一项目中使用 Visual Studio .NET ListBox 类,就必须使用完全限定的引用以使引用唯一。如果该引用不唯一,Visual Basic .NET 会产生错误,指出该名称不明确。下面的代码片断说明如何声明这些对象:

' Define a new object based on your ListBox class.
Dim LBC as New ListBox
' Define a new Windows.Forms ListBox control.
Dim MyLB as New System.Windows.Forms.ListBox
下图说明了两个命名空间层次结构,它们都包含名为 ListBox 的对象。





默认情况下,用 Visual Basic .NET 创建的可执行文件会包含与项目同名的命名空间。例如,如果在名为 ListBoxProject 的项目内定义一个对象,则可执行文件 (ListBoxProject.exe) 包含称为 ListBoxProject 的命名空间。

多个程序集可使用同一命名空间。Visual Basic .NET 将它们视为一个名称集。例如,可以在名为 Assemb1 的程序集中为名为 SomeNameSpace 的命名空间定义类,在名为 Assemb2 的程序集中为同一命名空间定义附加的类。

完全限定名
完全限定名是以定义对象的命名空间的名称为前缀的对象引用。如果创建对该类的引用(选择“项目”菜单中的“添加引用”),然后在代码中使用对象的完全限定名,就可以使用在其他项目中定义的对象。下面的代码片段说明如何使用另一项目命名空间中的对象的完全限定名:

Dim LBC As New ListBoxProject.Form1.ListBox()
因为编译器总能确定正在使用哪一个对象,完全限定名避免了名称冲突。然而,名称本身可能变得冗长繁琐。为避免这点,可以使用 Imports 语句来定义“别名”——可用来替代完全限定名的缩写名称。例如,下面的代码片断为两个完全限定名创建别名,并且使用这些别名定义两个对象:

Imports LBControl = System.Windows.Forms.ListBox

Imports MyListBox = ListBoxProject.Form1.ListBox

Dim LBC As LBControl

Dim MyLB As MyListBox

如果使用 Imports 语句而不用别名,可以不加限定地使用该命名空间中的所有名称,只要它们对项目而言是唯一的即可。如果项目包含的命名空间的 Imports 语句含有同名项,则使用该名称时必须完全限定它。例如,假设项目包含如下两个 Imports 语句:

Imports MyProj1 ' This namespace contains a class called Class1.
Imports MyProj2 ' This namespace also contains a class called Class1.
如果试图在没有完全限定的情况下使用 Class1,Visual Basic .NET 将产生错误,指出名称 Class1 不明确
下面的示例显示了如何为命名空间定义和使用 using 别名:

// cs_using_directive.cs
using MyAlias = MyCompany.Proj.Nested; // define an alias to represent a namespace

namespace MyCompany.Proj
{
public class MyClass
{
public static void DoNothing()
{
}
}

namespace Nested // a nested namespace
{
public class ClassInNestedNameSpace
{
public static void SayHello()
{
System.Console.WriteLine("Hello");
}
}
}

}

public class UnNestedClass
{
public static void Main()
{
MyAlias.ClassInNestedNameSpace.SayHello(); // using alias
}
}
输出
jonsonzxw 2003-01-14
  • 打赏
  • 举报
回复
1.命名空间和程序集
除了依赖于几个系统提供的类(如 System.Console),到目前为止介绍的程序都是独立存在的。但更常见的情况是:实际的应用程序由若干不同的部分组成,每个部分分别进行编译。例如,企业级应用程序可能依赖于若干不同的组件,其中包括某些内部开发的组件和某些从独立软件供应商处购买的组件。

命名空间和程序集启用此基于组件的系统。命名空间提供一个逻辑组织系统。命名空间既用作程序的“内部”组织系统,也用作“外部”组织系统(一种表示向其他程序公开的程序元素的方式)。

程序集用于物理打包和部署。程序集可以包含类型、用于实现这些类型的可执行代码以及对其他程序集的引用。

有两种主要的程序集:应用程序和库。应用程序有一个主入口点,通常具有 .exe 文件扩展名;而库没有主入口点,通常具有 .dll 文件扩展名。

为了说明命名空间和程序集的使用,本节再次以前面介绍的“hello, world”程序为例,并将它分为两个部分:提供消息的类库和显示消息的控制台应用程序。

该类库将包含单个名为 HelloMessage 的类。示例

// HelloLibrary.cs
namespace Microsoft.CSharp.Introduction
{
public class HelloMessage
{
public string Message {
get {
return "hello, world";
}
}
}
}
显示了名为 Microsoft.CSharp.Introduction 的命名空间中的 HelloMessage 类。HelloMessage 类提供一个名为 Message 的只读属性。命名空间可以嵌套,而声明

namespace Microsoft.CSharp.Introduction
{...}
是若干层命名空间嵌套的简写形式:

namespace Microsoft
{
namespace CSharp
{
namespace Introduction
{...}
}
}
将“hello, world”组件化的下一个步骤是编写使用 HelloMessage 类的控制台应用程序。可以使用此类的完全限定名 Microsoft.CSharp.Introduction.HelloMessage,但该名称太长,使用起来不方便。一种更方便的方法是使用“using 命名空间指令”,它允许在命名空间中使用所有类型而不必限定。示例

// HelloApp.cs
using Microsoft.CSharp.Introduction;
class HelloApp
{
static void Main() {
HelloMessage m = new HelloMessage();
System.Console.WriteLine(m.Message);
}
}
显示了一个引用 Microsoft.CSharp.Introduction 命名空间的 using 命名空间指令。出现的 HelloMessage 是 Microsoft.CSharp.Introduction.HelloMessage 的简写形式。

C# 还允许定义和使用别名。“using 别名指令”定义类型的别名。当两个类库之间发生名称冲突时,或者当使用大得多的命名空间中的少数类型时,这类别名很有用。示例

using MessageSource = Microsoft.CSharp.Introduction.HelloMessage;
显示了一个 using 别名指令,该指令将 MessageSource 定义为 HelloMessage 类的别名。

我们已编写的代码可以编译为包含类 HelloMessage 的类库和包含类 HelloApp 的应用程序。此编译步骤的细节可能因使用的编译器或工具而异。使用 Visual Studio .NET 中提供的命令行编译器时,正确的调用为

csc /target:library HelloLibrary.cs
这将产生类库 HelloLibrary.dll 和

csc /reference:HelloLibrary.dll HelloApp.cs
(这将产生应用程序 HelloApp.exe)。


2.委托启用某些其他语言已通过函数指针解决的方案。但与函数指针不同的是,委托是面向对象的、类型安全的和保险的。

委托声明定义一个从 System.Delegate 类派生的类。委托实例封装一个或多个方法,每个方法都被称为可调用的实体。对于实例方法,可调用的实体由一个实例和该实例的方法组成。对于静态方法,可调用实体仅由一个方法组成。已知委托实例和适当的参数集,可以用该参数集调用此委托实例的所有方法。

委托实例的一个有趣且有用的属性是:它不知道也不关心它封装的方法的类;对它来说最重要的是这些方法与委托的类型兼容(第 15.1 节)。这使委托非常适合“匿名”调用。这是一个强大的功能。

定义和使用委托分三个步骤:声明、实例化和调用。委托用委托声明语法来声明。示例

delegate void SimpleDelegate();
声明一个名为 SimpleDelegate 的委托,它不带参数并返回 void。

示例

class Test
{
static void F() {
System.Console.WriteLine("Test.F");
}
static void Main() {
SimpleDelegate d = new SimpleDelegate(F);
d();
}
}
创建一个 SimpleDelegate 实例,然后立即调用它。

不必实例化方法的委托然后立即通过该委托调用它,因为直接调用方法更简单。当使用委托的匿名时,委托真正显示出它的效用。示例

void MultiCall(SimpleDelegate d, int count) {
for (int i = 0; i < count; i++)
d();
}
}
显示了一个重复调用 SimpleDelegate 的 MultiCall 方法。MultiCall 方法不知道也不在乎 SimpleDelegate 的目标方法的类型、该方法所具有的可访问性以及该方法是否为静态。对它来说最重要的是目标方法与 SimpleDelegate 兼容(第 15.1 节)。

111,101

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • AIGC Browser
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧