1 使用RCW和CCW来访问
是否可以在 .NET 框架程序中使用 COM 对象?
是。您现在部署的任何 COM 组件都可以在托管代码中使用。通常情况下,所需的调整是完全自动进行的。
特别是,可以使用运行时可调用包装 (RCW) 从 .NET 框架访问 COM 组件。此包装将 COM 组件提供的 COM 接口转换为与 .NET 框架兼容的接口。对于 OLE 自动化接口,RCW 可以从类型库中自动生成;对于非 OLE 自动化接口,开发人员可以编写自定义 RCW,手动将 COM 接口提供的类型映射为与 .NET 框架兼容的类型。
是否可以在 COM 程序中使用 .NET 框架组件?
是。您现在创建的托管类型都可以通过 COM 访问。通常情况下,所需的配置是完全自动进行的。托管开发环境的某些新特性不能在 COM 中访问。例如,不能在 COM 中使用静态方法和参数化构造函数。一般,提前确定给定类型所针对的用户是一种较好的办法。如果类型需要在 COM 中使用,您将被限制在使用 COM 可访问的特性。
默认情况下,托管类型可能是可见的,也可能是不可见的,这由用于编写托管类型的语言决定。
特别是,可以使用 COM 可调用包装 (CCW) 从 COM 访问 .NET 框架组件。这与 RCW(请参阅上一个问题)相似,但它们的方向相反。同样,如果 .NET 框架开发工具不能自动生成包装,或者如果自动方式不是您所需要的,则可以开发自定义的 CCW。
re: 保护你的DLL和Code不被别人使用 梦在天涯 2006-07-24 09:14
使用ildasm 和ilasm反编译之后,去掉publickey 和.permissionset linkcheck
就可以正常引用了.
听说VS有自带的简单的混淆器咋个启用方法呀?
这个方法很容易破
用ildasm反编译后把头部的强名称删掉再用ilasm编译回去就能用了
方法不错,值得鼓励。MS的ReportingService里面就是这么干的,尽管可以用ILDasm来破解掉单个Assembly,但是当整个系统都采用这个策略的时候,全部破解很费精力。
re: 指针高级-- 梦在天涯 2006-07-12 12:02
恩,是有警告,说不能返回局部指针,也就是栈上的指针
re: 指针高级-- 梦在天涯 2006-07-07 13:18
直接编译:需要
#include <stdio.h>
#include <tchar.h>
re: Net 常用工具(free) 梦在天涯 2006-07-04 09:01
re: 非常简单的石头,剪刀,布程序 梦在天涯 2006-06-26 14:19
谢谢楼上的!
re: 非常简单的石头,剪刀,布程序 梦在天涯 2006-06-24 15:35
死循环????为什么不执行循环里的输入语句cin >> a;和cin >> b;???
re: 非常简单的石头,剪刀,布程序 梦在天涯 2006-06-24 14:39
输入字符或字符串的时候会.................
re: 性能测试类 梦在天涯 2006-06-16 14:26
GetTickCount()和GetCurrentTime()都只精确到55ms(1个tick就是55ms)。如果要精确到毫秒,应该使用timeGetTime函数或QueryPerformanceCounter函数。
虽然timeGetTime返回值的单位是1ms,但实际上它的精度只有10ms左右。
如果想提高精度,可以使用QueryPerformanceCounter和QueryPerformanceFrequency。这两个函数不是在每个系统中都支持。对于支持它们的系统中,可以获得低于1ms的精度。Windows 内部有一个精度非常高的定时器, 精度在微秒级, 但不同的系统这个定时器的频率不同, 这个频率与硬件和操作系统都可能有关。利用 API 函数 QueryPerformanceFrequency 可以得到这个定时器的频率。利用 API 函数 QueryPerformanceCounter 可以得到定时器的当前值。根据要延时的时间和定时器的频率, 可以算出要延时的时间定时器经过的周期数。在循环里用 QueryPerformanceCounter 不停的读出定时器值, 一直到经过了指定周期数再结束循环, 就达到了高精度延时的目的。
re: 单元测试小技巧 梦在天涯 2006-06-16 11:53
vista开发社区: http://devreadiness.org/default.aspx
纹理类
在托管的 Direct3D 中,与纹理相关的类从抽象类 Resource 继承,并且在极大程度上在与纹理相关的非托管接口上建立层。托管的 Direct3D 有三个纹理类:Texture、CubeTexture 和 VolumeTexture。Texture 类表示可映射到基元上的图像,用于呈现或用于凹凸贴图、法线贴图或其他效果。纹理的基本函数用于将一对纹理坐标映射到某个值(通常是颜色值),但是可以通过其他方式进行解释。纹理坐标通常是顶点数据的一部分。纹理坐标到颜色或其他值的映射是在呈现管线的像素处理阶段完成的。Direct3D 允许一次最多使用八个纹理。CubeTexture 类是用于立方体环境贴图的特殊种类的纹理,立方体环境贴图这种技术允许环境(如室内或外景)由反光物体反射出来,这是通过以下方法来实现的:使用纹理来为立方体周围的六个面各定义一个图像,并由所呈现的物体来反射。VolumeTexture 类表示存在于三维矩形空间中的颜色或其他值。同样,它将纹理坐标的三元组映射到颜色或其他值。这些类最重要的方面是,它们都支持一组用于锁定和取消锁定纹理的重载方法。
经常用于加载和保存纹理的类是 TextureLoader。TextureLoader 类包含用来从文件或流加载纹理、立方体纹理或体积纹理的方法。TextureLoader 类的其他用法包括填充和筛选纹理以及计算法线贴图。用来创建纹理的有用的 helper 方法由 GraphicsUtility 类提供:文件的 GraphicsUtility.CreateTexture 方法只是查找指定纹理的路径,然后调用 TextureLoader.FromFile 方法以加载它。以下代码说明了 GraphicsUtility 类的用法:
Texture texture = GraphicsUtility.CreateTexture(device,"banana.bmp");
设备类
托管的 Direct3D 提供了基于类的设备抽象,该抽象是通过使用非托管的 IDirect3DDevice9 接口实现的。编写 Direct3D 托管代码的程序员使用 Device 类的方法来访问其他 Direct3D 对象,以便设置各种图形状态并呈现几何形状。为了执行这些函数,Device 类提供了许多属性、方法和事件。图 2 列出了 Device 类最重要的方法,这些方法由 3D 应用程序调用。
谈到对象激活,一种观点认为,非托管的 Direct3D 之所以使用工厂方法,只是因为 COM 不支持新运算符。COM 的标准激活模式是基于工厂的构造。CoCreateInstance 函数模仿 COM 的新运算符,但它只是一个在内部使用 COM 工厂的包装。使用工厂(相对于新运算符)的另一个原理就是,在使用新运算符时,需要将对象的特定实现绑定到客户端的代码中;因此,如果大量使用新运算符,可能会导致版本控制问题。工厂方法通常用于将代码的客户端或用户与代码的创建者去耦。非托管的 COM IDirect3DDevice9 接口提供 14 种显式工厂方法,以便创建在使用 Direct3D 时需要的对象(如像素和顶点 Shader 以及顶点和索引缓冲区)。
目前,托管的 Direct3D 在很大程度上依赖于使用新运算符来构造类。尽管 Device 托管类只提供三种工厂方法,但是,一个值得注意的有趣现象是,非托管的 IDirect3DDevice9 工厂方法和由 Device 类公开的公共属性之间存在一对一关联。以下代码行说明了由 Device 托管类公开的三种工厂方法,每种方法都使用多个参数:
public Surface CreateRenderTarget(...);
public Surface CreateDepthStencilSurface(...);
public Surface CreateOffscreenPlainSurface(...);
在托管的 Direct3D 中大量使用方法重载。下面的代码示例说明了非托管的 Device.ColorFill 方法及其托管的重载包装:
typedef DWORD D3DCOLOR;
// Methods from the unmanaged IDirect3DDevice9 interface.
HRESULT ColorFill(IDirect3DSurface9 *pSurface, CONST RECT *pRect,
D3DCOLOR color);
// Methods from the managed Device class.
public void ColorFill(Surface surface, Rectangle rect, Color color);
public void ColorFill(Surface surface, Rectangle rect, int color);
与传统的图形系统一样,非托管的 Direct3D 需要将颜色值作为 32 位整数值在内部传递。另一方面,Microsoft .NET Framework 显式提供用来处理 ARGB 颜色值的 System.Drawing.Color 类,其中包含几种用来在不同表示形式之间进行转换的方法。为方便那些已习惯于使用整数值来表示颜色的程序员,托管的 Direct3D 在需要颜色参数时使用这两种表示形式来提供方法重载。
非托管的 IDirect3DDevice9 接口既公开只读属性,又公开读写属性,这两种属性都可以带参数,也可以不带参数。在最新版本的 .NET Framework 中,属性不带参数。因此,在将非托管的 Direct3D 映射到托管的 Direct3D 时,不使用参数的属性可以很好地映射到 C# 属性,而使用参数的 Direct3D 非托管属性只作为 Get 和 Set 方法公开。图 3 列出了 Device 类的一些最重要的属性。
最后,Direct3D Device 托管类提供了五个用来与设备进行交互的显式事件。基于 Direct3D 的应用程序可以通过以下方法来将事件作为 Device 的来源:启动应用程序、调整窗口的大小、从窗口模式更改到全屏模式或者退出应用程序。一个有趣的发现是由 Direct3D 使用的基于 .NET 委托的事件模式。对于 Device 类的每个事件声明,提供了添加、删除和引发方法,以及用来存储事件处理程序的私有实例变量。在 C# 中,客户端事件注册和注销的语法形式分别是通过 += 和 -= 运算符来提供的(请参阅图 4)。
图形状态类
如前所述,非托管代码的图形状态是通过 IDirect3DDevice9 接口的方法来配置的。例如,在非托管代码中,变换状态可通过 GetTransform 和 SetTransform 方法直接访问,这两种方法都使用 D3DTRANSFORMTYPE 类型的枚举值。
// From unmanaged IDirect3DDevice9 interface:
HRESULT GetTransform(D3DTRANSFORMSTATETYPE State, D3DMATRIX *pMatrix);
HRESULT SetTransform(D3DTRANSFORMSTATETYPE State,
CONST D3DMATRIX *pMatrix);
托管的 Direct3D 为非托管层提供一些抽象,这会使客户端代码变得更简洁。下面显示的 Device 类说明了一组只读属性:
public class Device : MarshalByRefObject, IDisposable
{
// Additional properties, methods and events.
public Transforms Transform { get; }
public RenderStates RenderState { get; }
public SamplerStates SamplerState { get; }
public TextureStates TextureState { get; }
}
这些属性返回 Transforms、RenderStates、SamplerStates 和 TextureStates 类的实例。这些实例随后用于配置托管 Direct3D 的图形状态。例如,Device 类不直接公开使用枚举值的 Transform 属性。Device 托管类提供可返回 Transforms 对象的属性。Transforms 对象随后公开一组可用来访问当前世界、视图和投影矩阵的属性,这些属性本身是 TransformType 托管枚举的元素。
RenderStates 类提供了大量的属性来配置为光栅化阶段选择的特定算法。下面的客户端代码显示了如何设置 Direct3D 托管管线的状态。
// cull, spec, dither states.
device.RenderState.CullMode = Cull.None;
device.RenderState.SpecularEnable = false;
device.RenderState.DitherEnable = false;
// Filter states.
device.SamplerState[0].MagFilter = TextureFilter.Linear;
device.SamplerState[0].MinFilter = TextureFilter.Linear;
请注意,使用索引器来访问取样器状态的多纹理层叠所在的阶段。
取样器状态指定用于特定阶段的筛选、平铺和纹理寻址模式,这些模式可通过 Sampler 类的属性来公开。筛选功能用于指定如何将图像映射到特定的 Direct3D 基元。根据图像(纹理)的大小以及它需要映射到的屏上基元的大小,可能需要放大或缩小图像。Direct3D 提供了三种筛选方法:MipFilter、MinFilter 和 MagFilter,每种方法都具有可由 TextureFilter 枚举配置的模式。平铺功能用于将一组单个的纹理汇集成单个纹理并减少切换纹理的需要。平铺功能是通过 Sampler 类的一组属性获得支持的。最后,纹理寻址模式通过 TextureAddress 枚举的元素为 [0,1] 边界外部的纹理坐标定义操作:
public class SamplerStates
{
private Sampler[] m_lpTex;
private bool pureDevice;
public Sampler get_SamplerState(int index);
internal SamplerStates(Device dev, bool pure);
public Sampler this[int index] { get; }
}
TextureStates 和 SamplerStates 类提供只读索引器,该索引器可返回特定阶段的 TextureState 实例。TextureState 类定义的属性可获得或指定特定纹理阶段状态的元素。诸如 ColorArgumentn 或 AlphaArgumentn(其中 n 可以是 0、1 或 2)属性可以是 TextureArgument 枚举的元素,而 ColorOperation 或 AlphaOperation 可以属于 TextureOperation 枚举,如下所示:
// color = tex mod diffuse.
device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
device.TextureState[0].ColorOperation = TextureOperation.Modulate;
device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
// alpha = select texture alpha.
device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;
device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
device.TextureState[0].AlphaArgument1 = TextureArgument.Diffuse;
与几何形状相关的类
Direct3D 中的几何形状被定义为顶点定义的数组。不同的图形算法需要存储在每个顶点的不同信息,了解这一点很重要。这些顶点组分需要由应用程序进行声明,具体情况取决于程序员希望实现的效果。例如,如果程序员希望将纹理映射到 Direct3D 将呈现的几何形状,则程序员必须进行如下声明:在每个顶点,都将有 tu 和 tv 值(纹理坐标)。托管的 Direct3D 提供了两种顶点定义机制:VertexFormats 和 VertexDeclarations。使用这些机制,可以在每个顶点定义其他数据,如颜色、混合权重、纹理坐标或应用程序定义的任何用法。作为一种方便的方法,为经常使用的顶点格式定义提供了 CustomVertex helper 类。CustomVertex 类提供 11 种不同的顶点定义,这些定义经常用于 Direct3D 应用程序中。
在托管的 Direct3D 中,应用程序用来定义其顶点布局的顶点格式由 Device 类的读和写 VertexFormat 属性来访问。VertexFormat 属性访问 VertexFormats 枚举的元素,并且只需通过以下方法来实现:针对 IDirect3DDevice9 接口使用 GetFVF 和 SetFVF 方法,调用内部的非托管 Direct3D Device COM 对象。托管的 VertexFormats 枚举映射到在 d3dtypes.h 中定义的 VertexFormat 常量位,如下所示:
public struct Vertex
{
public Vector3 position;
public float tu, tv;
public static readonly VertexFormats Format =
VertexFormats.Position | VertexFormats.Texture1;
};
// From a typical managed Direct3D applications Render() method.
device.VertexFormat = Vertex.Format;
在使用可编程的管线时,需要自定义的顶点声明。与使用灵活的顶点格式定义的顶点缓冲区不同,自定义顶点声明可以通过使用多个流来定义,从而可节省带宽:
VertexElement[] declaration = new VertexElement[]
{
new VertexElement(
0, // short stream
0, // short offset
DeclarationType.Float2, // DeclarationType declType
DeclarationMethod.Default, // DeclarationMethod declMethod
DeclarationUsage.Position, // DeclarationUsage declUsage
0 // byte usageIndex
),
VertexElement.VertexDeclarationEnd
};
VertexDeclaration declaration = new VertexDeclaration(device,
declaration);
托管 Direct3D 中的几何形状通常是通过处理 VertexBuffer.Created 事件来创建的。图 5 显示了从 SDK 中的 Tutorial2 示例提取的简单三角形形状,并说明了预定义的自定义顶点 (CustomVertex.TransformedColored) 的用法。
托管的 D3DX 库
托管的 D3DX 实用工具库具有用来处理网格、纹理、Shader、效果、文本和动画的类。但是,与非托管的 D3DX 库不同的是,它没有数学类,如矩阵、矢量和四元组类。在托管 DirectX 中,数学类是 DirectX 库的一部分。
用来处理网格的类包括 Mesh、SimplificationMesh、ProgressiveMesh、SkinMesh 和 PatchMesh。Mesh 和 ProgressiveMesh 从 BaseMesh 类继承。BaseMesh 管理内存(包括顶点和索引缓冲区)中的网格表示形式,并提供用来呈现网格的 DrawSubset 方法。其他方法包括用来复制网格的 Clone 方法,以及用来计算顶点法线并获取相邻项信息的方法。
Mesh 类使用可将网格保存到 .X 文件(标准的 DirectX 文件类型)或二进制流中并从中加载网格的方法来扩展 BaseMesh。还提供了用来生成表示以下图形的网格的方法:n 边形、圆柱、球形、圆环、给定字体的 3D 文本或者甚至是茶壶。用户可以网格化网格以获得更光滑的对象(通过将每个三角形解释为 N-patch),简化网格(通过减少三角形的数量)、优化网格(通过对三角形重新排序,以便利用硬件中的顶点缓存并提高性能)或者执行与网格的光交叉。
SimplificationMesh 对象是从 Mesh 构造的,它具有可减少表面(三角形)或顶点数量的方法,从而可产生比初始网格简单但是质量更低的网格形式。ProgressiveMesh 对象是从 Mesh 构造的。它允许实时简化网格,以便在网格对象和照相机之间的距离增大时,最小化所呈现三角形的数量。SkinMesh 类(由主干制作动画的网格)提供的方法可用来从 .X 文件数据对象加载外观网格。包含了用来公开基础网格和外观的信息(如每根骨头对结构的影响)的属性。
PatchMesh 类表示更高阶的表面,如 N-Patch、Triangle Patch 或 Rectangle Patch 表面。PatchMesh 包括用来执行如下操作的方法:从 Mesh 对象创建 N-Patch 网格、从 .X 文件加载 PatchMesh、网格化 PatchMesh 等。用来处理纹理的类主要包括:前面介绍的 TextureLoader 类、RenderToEnvironmentMap 类和 RenderToSurface 类。RenderToEnvironmentMap 和 RenderToSurface 类用来在运行时创建立方体环境贴图和纹理。如果在运行时呈现到纹理中,则允许您获得特殊效果,如让类似于镜面的物体反射布景中的其他物体,或者制造双窗格呈现效果。用来处理文本的类主要包括 Font 类,Font 类可以从 System.Drawing.Font 对象实例化,并且具有可以在支持 Direct3D 的设备上呈现文本的方法。用来处理动画的类由 KeyFrameInterpolator 类组成,KeyFrameInterpolator 类具有用来以内插值替换对象的缩放、旋转和/或平移的方法。内插值替换是通过使用一组 3D 矢量(用来缩放和平移)和四元组项(用于旋转)来执行的。
都有这个device.SetStreamSource(0, vertexBuffer, 0);
她的作用?可以不要吗?
用处: 在c++中用基类指针的数组,在c#中用arraylist都可以 来表示一个带有分支的树结构
用户感觉不到他在处理结合还是一个单体> 这就是此模式的用处所在
re: 雅虎公司C#笔试题[转] 梦在天涯 2006-05-18 12:55
小弟最近在CSDN上找的C#面试题目,自己做了一下把题目和答案附上来,希望对大家有用。如有错误的地方还望大家指教!
1、C#中 property 与 attribute的区别,他们各有什么用处,这种机制的好处在哪里?
property和attribute汉语都称之为属性。不过property是指类向外提供的数据区域。而attribute则是描述对象在编译时或运行时属性的。这两者是有本质区别的。
2、讲一讲你理解的web service,在dot net framework中,怎么很好的结合xml?(讲概念就行了)
从表面上看,Web Service就是一个应用程序,它向外界暴露出一个能够通过Web进行调用的API。这就是说,你能够用编程的方法通过Web调用来实现某个功能的应用程序。从深层次上看,Web Service是一种新的Web应用程序分支,它们是自包含、自描述、模块化的应用,可以在网络(通常为Web)中被描述、发布、查找以及通过Web来调用。可扩展的标记语言XML是Web Service平台中表示数据的基本格式。除了易于建立和易于分析外,XML主要的优点在于它既与平台无关,又与厂商无关。XML是由万维网协会(W3C)创建,W3C制定的XML SchemaXSD定义了一套标准的数据类型,并给出了一种语言来扩展这套数据类型。Web Service平台是用XSD来作为数据类型系统的。当你用某种语言如VB.NET或C#来构造一个Web Service时,为了符合Web Service标准,所有你使用的数据类型都必须被转换为XSD类型。如想让它使用在不同平台和不同软件的不同组织间传递,还需要用某种东西将它包装起来。这种东西就是一种协议,如 SOAP。
3. C#, Java 和 c++的特点,有什么相同的地方,不同的地方,C#分别从c++和java中吸取了他们那些优点?
C#看起来与Java有着惊人的相似;它包括了诸如单一继承,界面,与Java几乎同样的语法,和编译成中间代码再运行的 过程.但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成。
微软c#语言定义主 要是从C和C++继承而来的,而且语言中的许多元素也反映了这一点.C#在设计者从C++继承的可选选项方面比Java要广泛一些(比如说 structs),它还增加了自己新的特点(比方说源代码版本定义).
C#从Java继承而来的特点
类:在C#中类的申明与Java很相似。特点看起来与Java相比没有变化.布尔运算:条件表达式的结果是布尔数据类型,布尔数据类型是这种语言中独立的一种数据类型.从布尔类型到其他类型没有 直接的转换过程.布尔常量true和false是C#中的关键字.错误处理:如Java中那样,通过抛出和捕捉异常对象来管理错误处理过程.内存管理:由 底层.NET框架进行自动内存垃圾回收.
C#从C和C++继承的特点
编译:程序直接编译成标准的二进制可执行形式.
结构体:一个C#的结构体与C++的结构体是相似的,因为它能够包含数据申明和方法.但是,不象C++,C#结构体与类是不同的而且不支持继承.但是,与Java相同的是,一个结构体可以实现界面.
预编译:C#中存在预编译指令支持条件编译,警告,错误报告和编译行控制. #error
C#独有的特点
中间代码:微软在用户选择何时MSIL应该编译成机器码的时候是留了很大的余地.微软公司很小心的声称MSIL不是解释性的,而是被编译成了机器码.它也明 白许多--如果不是大多数的话--程序员认为Java程序要不可避免的比C编写的任何东西都要慢.而这种实现方式决定了基于MSIL的程序(指的是用 C#,Visual Basic,"Managed C++"--C++的一个符合CLS的版本--等语言编写的程序)将在性能上超过"解释性的"Java代码.当然,这一点还需要得到事实证明,因为C#和 其他生成MSIL的编译器还没有发布.但是Java JIT编译器的普遍存在使得Java和C#在性能上相对相同.象"C#是编译语言而Java是解释性的,"之类的声明只是商业技巧.Java的中间代码和 MSIL都是中间的汇编形式的语言,它们在运行时或其它的时候被编译成机器代码.
命名空间中的申明:当你创建一个程序的时候,你在一个命名空间里创建了一个或多个类.同在这个命名空间里(在类的外面)你还有可能声明界面,枚举类型和结构体.必须使用using关键字来引用其他命名空间的内容.
基本的数据类型:C#拥有比C,C++或者Java更广泛的数据类型.这些类型是bool, byte, ubyte, short, ushort, int, uint, long, ulong, float, double,和decimal.象Java一样,所有这些类型都有一个固定的大小.又象C和C++一样,每个数据类型都有有符号和无符号两种类型.与 Java相同的是,一个字符变量包含的是一个16位的Unicode字符.C#新的数据类型是decimal数据类型,对于货币数据,它能存放28位10 进制数字.
两个基本类:一个名叫object的类是所有其他类的基类.而一个名叫string的类也象object一样是这个语言的一部分.作为语言的一部分存在意味着编译器有可能使用它--无论何时你在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它.
参数传递:方法可以被声明接受可变数目的参数.缺省的参数传递方法是对基本数据类型进行值传递.ref关键字可以用来强迫一个变量通过引用传递,这使得一个变量可以接受一个返回值.out关键字也能声明引用传递过程,与ref不同的地方是,它指明这个参数并不需要初始值.
与COM 的集成:C#对Windows程序最大的卖点可能就是它与COM的无缝集成了,COM就是微软的Win32组件技术.实际上,最终有可能在任何.NET语 言里编写COM客户和服务器端.C#编写的类可以子类化一个以存在的COM组件;生成的类也能被作为一个COM组件使用,然后又能使用,比方说, JScript语言子类化它从而得到第三个COM组件.这种现象的结果是导致了一个运行环境的产生,在这个环境里的组件是网络服务,可用用任何.NET语 言子类化.
索引下标:一个索引与属性除了不使用属性名来引用类成员而是用一个方括号中的数字来匿名引用(就象用数组下标一样)以外是相似的.
代理和反馈:一个代理对象包括了访问一个特定对象的特定方法所需的信息.只要把它当成一个聪明的方法指针就行了.代理对象可以被移动到另一个地方,然后可以 通过访问它来对已存在的方法进行类型安全的调用.一个反馈方法是代理的特例.event关键字用在将在事件发生的时候被当成代理调用的方法声明中.
re: 我把初恋搞丢了(原创) 梦在天涯 2006-05-18 08:58
时间会解决一切,一切都会好起来的啊!
Managed DirectX是对DirectX大部分功能的托管封装,可以用任何支持.NET的语言开发。MDX只对DirectX做了非常低层次的封装,因此保持了用COM接口DirectX开发时的大部分原貌。MDX的性能是不用担心的,因为它还是象COM DirectX一样提供对硬件层次的访问,大部分功能都是在你的显卡/网卡/声卡上起作用的,托管部分只是它的接口。事实证明MDX在DirectX Graphics中的性能与COM接口的DirectX不相上下。既然MDX的开发方式、API和性能都与COM接口的DirectX差不多,那为什么要用MDX呢?我自己对这个问题的回答是:
1、托管代码的对象模型更好。MDX基于类库的组织结构,比用COM接口的处理方式更方便。
2、用MDX,一般不用操心资源释放的问题。很大一部分资源释放的操作,都被封装好了。
3、与更多现代技术结合得更好。我们可以让DirectX程序使用XML、WebService和智能客户端等技术。
Direct3D程序最基本的流程是:创建Windows窗口、创建设备、处理消息循环、物体图形显示、退出和清理。在MDX的世界里,窗口创建和处理消息循环我们交给Windows Forms模型来做,剩下最主要的任务就是创建设备和物体图形显示。Direct3D设备是Direct3D开发最基本的入口,它定义了Direct3D所有的绘图组件,大部分的操作都需要从Direct3D设备开始。创建设备需要设定几个参数,包括显卡序号、设备类型、所属窗口、3D运算方式等。除了这些信息外,还需要一个PresentParameters类型的参数,其中定义了Direct3D设备所需的相关信息。下面代码中的InitializeDirect3D函数完整的演示了创建设备的步骤
设备类型:Direct3D支持3种设备,其中HAL和REF最为重要。HAL通过硬件进行光栅化、坐标变换和光照处理等,速度最快。REF则是用软件实现相关的操作,仅用于硬件不支持某种操作的情况。DeviceType枚举定义了设备类型可能的选项。
3D运算方式包括一些选项,如HardwareVertexProcessing,PureHardwareVertexProcessing等,用于指定顶点运算由硬件执行还是软件执行等。
PresentParameters还包括一些设置,如后台缓冲区的高度、宽度和像素格式,以及从后台缓冲区复制到前台缓存屏幕显示的方式等等。如果Direct3D采用窗口方式运行,像素格式必须查询当前的显示模式获得。
Direct3D设备创建成功以后,就可以进入图形显示阶段。在下面的代码中以Render()函数的形式出现。在绘制图形前,需要调用Device::Clear()函数重制ViewPort的颜色缓冲区。ViewPort就是3D形状投射到平面显示器上供我们看到的那个区域。Clear函数的Flag参数指定了对颜色缓冲区、深度缓冲区还是模板缓冲区进行初始化。因为我用ATI显卡,所以我选择了将颜色缓冲区初始化为红色:)。接下来是调用BeginScene()函数和EndScene()函数。实际的绘图中,所有渲染的代码都必须放在BeginScene函数和EndScene函数之间,否则就会出错。最后调用Present()函数,将后台缓冲区中的数据复制到前台缓冲区,我们就能看见图形了。
IT公司类
包括思科、英特尔、IBM、惠普、ACER、索尼、Oracle、联想、长城、同方、方正、洪恩、微软、汉王、神州数码、京东方、维尔软件、普天、奇码数字信息有限公司、广东北电、威盛、高通、扬智、友立资讯、BISC、GOOGLE、SUN、腾讯公司、百度等
通讯/运营类
中国电信、中国移动、中国联通、中国网通、中国铁通、华为、中兴、大唐、UT斯达康、上海贝尔阿尔卡特、摩托罗拉、诺基亚、爱立信、西门子、朗讯、香港电信、东信、北京信威通信、飞利浦、NEC
电子电气类
意法半导体、Avant! 微电子、凹凸电子、松下电器、美的集团、创维集团、厦新、TCL、北京松下彩色显像管有限公司、中星微电子、美国国家仪器有限公司(NI)、士兰微电子、世芯电子股份有限公司、奥的斯(otis)、青岛海信集团技术中心
金融/投资
中国工商银行、中国建设银行、中国银行、中国农业银行、中国招商银行、中国国际金融有限公司(CICC)、Hongkong Bank、中软融鑫、高盛(GS)、博世(BOSCH)、宝洁(Procter&Gamble)、沃尔玛
http://www.net3721.com/bbs/forumdisplay.php?fid=43
re: c# sort()自定义的结构 梦在天涯 2006-04-30 16:58
但是 .net 2.0 中不支持用delegate() 来sort().
re: XML Comments in C# 梦在天涯 2006-04-30 16:25
很好用的啊,但是好像没有最新的支持.net 2.0的啊!
re: IT高薪必读 梦在天涯 2006-04-26 09:02
转的!
在什么情况下应当使用访问者模式
有意思的是,在很多情况下不使用设计模式反而会得到一个较好的设计。换言之,每一个设计模式都有其不应当使用的情况。访问者模式也有其不应当使用的情况,让我们
先看一看访问者模式不应当在什么情况下使用。
倾斜的可扩展性
访问者模式仅应当在被访问的类结构非常稳定的情况下使用。换言之,系统很少出现需要加入新节点的情况。如果出现需要加入新节点的情况,那么就必须在每一个访问对象里加入一个对应于这个新节点的访问操作,而这是对一个系统的大规模修改,因而是违背"开一闭"原则的。
访问者模式允许在节点中加入新的方法,相应的仅仅需要在一个新的访问者类中加入此方法,而不需要在每一个访问者类中都加入此方法。
显然,访问者模式提供了倾斜的可扩展性设计:方法集合的可扩展性和类集合的不可扩展性。换言之,如果系统的数据结构是频繁变化的,则不适合使用访问者模式。
"开一闭"原则和对变化的封装
面向对象的设计原则中最重要的便是所谓的"开一闭"原则。一个软件系统的设计应当尽量做到对扩展开放,对修改关闭。达到这个原则的途径就是遵循"对变化的封装"的原则。这个原则讲的是在进行软件系统的设计时,应当设法找出一个软件系统中会变化的部分,将之封装起来。
很多系统可以按照算法和数据结构分开,也就是说一些对象含有算法,而另一些对象含有数据,接受算法的操作。如果这样的系统有比较稳定的数据结构,又有易于变化的算法的话,使用访问者模式就是比较合适的,因为访问者模式使得算法操作的增加变得容易。
反过来,如果这样一个系统的数据结构对象易于变化,经常要有新的数据对象增加进来的话,就不适合使用访问者模式。因为在访问者模式中增加新的节点很困难,要涉及到在抽象访问者和所有的具体访问者中增加新的方法。
六、 使用访问者模式的优点和缺点
访问者模式有如下的优点:
访问者模式使得增加新的操作变得很容易。如果一些操作依赖于一个复杂的结构对象的话,那么一般而言,增加新的操作会很复杂。而使用访问者模式,增加新的操作就意味着增加一个新的访问者类,因此,变得很容易。
访问者模式将有关的行为集中到一个访问者对象中,而不是分散到一个个的节点类中。
访问者模式可以跨过几个类的等级结构访问属于不同的等级结构的成员类。迭代子只能访问属于同一个类型等级结构的成员对象,而不能访问属于不同等级结构的对象。访问者模式可以做到这一点。
积累状态。每一个单独的访问者对象都集中了相关的行为,从而也就可以在访问的过程中将执行操作的状态积累在自己内部,而不是分散到很多的节点对象中。这是有益于系统维护的优点。
访问者模式有如下的缺点:
增加新的节点类变得很困难。每增加一个新的节点都意味着要在抽象访问者角色中增加一个新的抽象操作,并在每一个具体访问者类中增加相应的具体操作。
破坏封装。访问者模式要求访问者对象访问并调用每一个节点对象的操作,这隐含了一个对所有节点对象的要求:它们必须暴露一些自己的操作和内部状态。不然,访问者的访问就变得没有意义。由于访问者对象自己会积累访问操作所需的状态,从而使这些状态不再存储在节点对象中,这也是破坏封装的。
访问者模式的目的是封装一些施加于某种数据结构元素之上的操作。一旦这些操作需要修改的话,接受这个操作的数据结构则可以保持不变。
问题提出
System.Collection命名空间下提供了大量集合操作对象。但大多数情况下处理的都是同类对象的聚集。换言之,在聚集上采取的操作都是一些针对同类型对象的同类操作。但是如果针对一个保存有不同类型对象的聚集采取某种操作该怎么办呢?
粗看上去,这似乎不是什么难题。可是如果需要针对一个包含不同类型元素的聚集采取某种操作,而操作的细节根据元素的类型不同而有所不同时,就会出现必须对元素类型做类型判断的条件转移语句。这个时候,使用访问者模式就是一个值得考虑的解决方案。
访问者模式
访问者模式适用于数据结构相对未定的系统,它把数据结构和作用于结构上的操作之间的耦合解脱开,使得操作集合可以相对自由地演化。
数据结构的每一个节点都可以接受一个访问者的调用,此节点向访问者对象传入节点对象,而访问者对象则反过来执行节点对象的操作。这样的过程叫做"双重分派"。节点调用访问者,将它自己传入,访问者则将某算法针对此节点执行。
双重分派意味着施加于节点之上的操作是基于访问者和节点本身的数据类型,而不仅仅是其中的一者。
re: 模式设计c#--行为型--state 梦在天涯 2006-04-25 14:33
State模式与Strategy模式的区别时什么啊?,potian大侠帮忙。
首先,两者的意图是不同的。策略用来处理算法变化,而状态则是透明地处理状态变化。
造成混淆的原因可能是两者好像都能成为继承的替代。
策略主要处理算法变化的意思是算法可能是要变的,但是这种变化却是由用户来决定到底采用何种算法。这些算法之间一般来说没有状态变迁的问题,并且你总是从几个算法中间选取一个。策略最经典的用法是和observe一起组成MVC,其中V通过Observe观察M,而V通过strategy控制C.
策略使用的另一个最频繁的地方就是消除大量的Case或if else ,但是条件是这些case中每个条件可以归纳为一个算法,最好它们只需要相同的参数。当然,在strategy中,Context可以提供接口让strategy,但是我一般不太喜欢这么用,因为这样可能造成一系列的不必要耦合和开销。
对这些case,if else使得strategy有了一个policy的别名,还有一个常用的地方叫做validator,譬如在输入框内进行检查时可以把它实现为Validator。有时候,if else的嵌套层次可能很深,这时候策略可能不能用,那么你可能需要更加复杂或者更加专注的Rule模式。
状态模式则有所不同,她实现的一个概念可以叫做动态继承,也就是继承的子类(每一个状态)可以发生变化。这些状态的变化是一个整体,组成了一个状态变化图。而一般来说,使用该模式的状态之间存在着一种线性变化的关系,也就是一个状态变为另一个,然后是第三个。客户代码并不清楚这些状态在何时发生变化,这样做的好处是在组成你整个变化过程中某些状态之间需要插入一个新的状态,或者状态的顺序之间发生变化,对客户是不可见。实现模式一方面,修改的也只是相领的状态。在处于不同的状态时,客户代码可以执行的方法也是不同的。但它的问题就是必须在Context和所有的状态实现所有状态可能的方法。
这两个之间的区别有时候可能没有,譬如在面向连结的TCPConnection例子中,不同的状态可能具有不同的方法。但是在我刚刚实现的一个无连结的P2P底层协议中,所有状态需要处理地就是一个processXML方法,这时候,你可以叫它状态或者策略都可以。但由于还是又状态变迁的问题,所以我喜欢把它叫做状态。
比较简单了,在net里太多的集合类拉,哈哈,就是那2个interface.
在什么情况下应当使用命令模式
在下面的情况下应当考虑使用命令模式:
1、使用命令模式作为"CallBack"在面向对象系统中的替代。"CallBack"讲的便是先将一个函数登记上,然后在以后调用此函数。
2、需要在不同的时间指定请求、将请求排队。一个命令对象和原先的请求发出者可以有不同的生命期。换言之,原先的请求发出者可能已经不在了,而命令对象本身仍然是活动的。这时命令的接收者可以是在本地,也可以在网络的另外一个地址。命令对象可以在串形化之后传送到另外一台机器上去。
3、系统需要支持命令的撤消(undo)。命令对象可以把状态存储起来,等到客户端需要撤销命令所产生的效果时,可以调用undo()方法,把命令所产生的效果撤销掉。命令对象还可以提供redo()方法,以供客户端在需要时,再重新实施命令效果。
4、如果一个系统要将系统中所有的数据更新到日志里,以便在系统崩溃时,可以根据日志里读回所有的数据更新命令,重新调用Execute()方法一条一条执行这些命令,从而恢复系统在崩溃前所做的数据更新。
5、一个系统需要支持交易(Transaction)。一个交易结构封装了一组数据更新命令。使用命令模式来实现交易结构可以使系统增加新的交易类型。
八、 使用命令模式的优点和缺点
命令允许请求的一方和接收请求的一方能够独立演化,从而且有以下的优点:
命令模式使新的命令很容易地被加入到系统里。
允许接收请求的一方决定是否要否决(Veto)请求。
能较容易地设计-个命令队列。
可以容易地实现对请求的Undo和Redo。
在需要的情况下,可以较容易地将命令记入日志。
命令模式把请求一个操作的对象与知道怎么执行一个操作的对象分割开。
命令类与其他任何别的类一样,可以修改和推广。
你可以把命令对象聚合在一起,合成为合成命令。比如宏命令便是合成命令的例子。合成命令是合成模式的应用。
由于加进新的具体命令类不影响其他的类,因此增加新的具体命令类很容易。
命令模式的缺点如下:
使用命令模式会导致某些系统有过多的具体命令类。某些系统可能需要几十个,几百个甚至几千个具体命令类,这会使命令模式在这样的系统里变得不实际。
职责链(Chain of Responsibility)模式
责任链模式是一种对象的行为模式【GOF95】。在责任链模式里,很多对象由每一个对象对其下家的引用而连接起来形成一条链。请求在这个链上传递,直到链上的某一个对象决定处理此请求。发出这个请求的客户端并不知道链上的哪一个对象最终处理这个请求,这使得系统可以在不影响客户端的情况下动态地重新组织链和分配责任。
re: 模式设计c#--结构型--proxy 梦在天涯 2006-04-24 16:05
我想Proxy与Adapter还是有区别的。因为Proxy中的代理和被代理对象是“同根生”,这样才可以代理。Adapter中的Adapter与Adaptee不用“同根生”。我把Proxy称作“票贩子的模式”,而Adapter是“倒卖外汇的模式”。票贩子贩的是票,在贩卖的过程中,票没有变化,只是被代理了。而Adapter模式中,外汇可能由人民币变做了美元,东西变了(呵呵,换汤不换药,都是钞票)。
re: 模式设计c#--结构型--proxy 梦在天涯 2006-04-24 16:05
好像和装饰(Decorator)模式差不多啊?
到底有什么不同啊?
在什么情况下使用门面模式
为一个复杂子系统提供一个简单接口
提高子系统的独立性
在层次化结构中,可以使用Facade模式定义系统中每一层的入口。
使用装饰模式的优点和缺点
使用装饰模式主要有以下的优点:
装饰模式与继承关系的目的都是要扩展对象的功能,但是装饰模式可以提供比继承更多的灵活性。
通过使用不同的具体装饰类以及这些装饰类的排列组合,设计师可以创造出很多不同行为的组合。
这种比继承更加灵活机动的特性,也同时意味着装饰模式比继承更加易于出错。
使用装饰模式主要有以下的缺点:
由于使用装饰模式,可以比使用继承关系需要较少数目的类。使用较少的类,当然使设计比较易于进行。但是,在另一方面,使用装饰模式会产生比使用继承关系更多的对象。更多的对象会使得查错变得困难,特别是这些对象看上去都很相像。
装饰模式应当在什么情况下使用
在以下情况下应当使用装饰模式:
需要扩展一个类的功能,或给一个类增加附加责任。
需要动态地给一个对象增加功能,这些功能可以再动态地撤销。
需要增加由一些基本功能的排列组合而产生的非常大量的功能,从而使继承关系变得不现实。
装饰(Decorator)模式又名包装(Wrapper)模式[GOF95]。装饰模式以对客户端透明的方式扩展对象的功能,是继承关系的一个替代方案。
桥梁模式的用意
【GOF95】在提出桥梁模式的时候指出,桥梁模式的用意是"将抽象化(Abstraction)与实现化(Implementation)脱耦,使得二者可以独立地变化"。这句话有三个关键词,也就是抽象化、实现化和脱耦。
抽象化
存在于多个实体中的共同的概念性联系,就是抽象化。作为一个过程,抽象化就是忽略一些信息,从而把不同的实体当做同样的实体对待【LISKOV94】。
实现化
抽象化给出的具体实现,就是实现化。
脱耦
所谓耦合,就是两个实体的行为的某种强关联。而将它们的强关联去掉,就是耦合的解脱,或称脱耦。在这里,脱耦是指将抽象化和实现化之间的耦合解脱开,或者说是将它们之间的强关联改换成弱关联。
将两个角色之间的继承关系改为聚合关系,就是将它们之间的强关联改换成为弱关联。因此,桥梁模式中的所谓脱耦,就是指在一个软件系统的抽象化和实现化之间使用组合/聚合关系而不是继承关系,从而使两者可以相对独立地变化。这就是桥梁模式的用意。
在什么情况下应当使用桥梁模式
根据上面的分析,在以下的情况下应当使用桥梁模式:
如果一个系统需要在构件的抽象化角色和具体化角色之间增加更多的灵活性,避免在两个层次之间建立静态的联系。
设计要求实现化角色的任何改变不应当影响客户端,或者说实现化角色的改变对客户端是完全透明的。
一个构件有多于一个的抽象化角色和实现化角色,系统需要它们之间进行动态耦合。
虽然在系统中使用继承是没有问题的,但是由于抽象化角色和具体化角色需要独立变化,设计要求需要独立管理这两者。
Adapter模式在实现时有以下这些值得注意的地方:
1、 目标接口可以省略,模式发生退化。但这种做法看似平庸而并不平庸,它可以使Adaptee不必实现不需要的方法(可以参考Default Adapter模式)。其表现形式就是父类实现缺省方法,而子类只需实现自己独特的方法。这有些像模板(Template)模式。
2、 适配器类可以是抽象类。
3、 带参数的适配器模式。使用这种办法,适配器类可以根据参数返还一个合适的实例给客户端。
在以下各种情况下使用适配器模式:
1、 系统需要使用现有的类,而此类的接口不符合系统的需要。
2、 想要建立一个可以重复使用的类,用于与一些彼此之间没有太大关联的一些类,包括一些可能在将来引进的类一起工作。这些源类不一定有很复杂的接口。
3、 (对对象适配器而言)在设计里,需要改变多个已有子类的接口,如果使用类的适配器模式,就要针对每一个子类做一个适配器,而这不太实际。
原型模式的用意是:通过给出一个原型对象来指明所要创建的对象类型,然后用复制这个原型对象的办法创建出更多的同类型对象。
Prototype模式的优点与缺点
Prototype模式的优点包括
1、Prototype模式允许动态增加或减少产品类。由于创建产品类实例的方法是产批类内部具有的,因此增加新产品对整个结构没有影响。
2、Prototype模式提供了简化的创建结构。工厂方法模式常常需要有一个与产品类等级结构相同的等级结构,而Prototype模式就不需要这样。
3、Portotype模式具有给一个应用软件动态加载新功能的能力。由于Prototype的独立性较高,可以很容易动态加载新功能而不影响老系统。
4、产品类不需要非得有任何事先确定的等级结构,因为Prototype模式适用于任何的等级结构。
Prototype模式的缺点:
Prototype模式的最主要缺点就是每一个类必须配备一个克隆方法。而且这个克隆方法需要对类的功能进行通盘考虑,这对全新的类来说不是很难,但对已有的类进行改造时,不一定是件容易的事