C# 教程 在线

2436C# 不安全代码

添加关键字 unsafe 后的代码会被 VS 编译环境报错。报错信息为 “不安全代码只会在使用 /unsafe 编译的情况下出现”

解决方法:

  • 1.此时需要在上方的 "项目" 菜单中找到 (项目标识符) 属性 项。单击进入项目属性设置界面。

  • 2.在项目属性界面中找到 "生成" 选项卡。
  • 3.在 "生成" 选项卡中找到 "允许不安全代码",勾选该项。

  • 4.此时再编译程序,就可以完全解决此问题了。

或者在 DOS 下使用编译命令如:csc /unsafe Unsafe.cs(Unsafe.cs 只是举例用的一个源代码文件)。

2435C# 不安全代码

fixed关键字

由于C#中声明的变量在内存中的存储受垃圾回收器管理;因此一个变量(例如一个大数组)有可能在运行过程中被移动到内存中的其他位置。如果一个变量的内存地址会变化,那么指针也就没有意义了。

解决方法就是使用fixed关键字来固定变量位置不移动。

static unsafe void Main(string[] args)
{
  fixed(int *ptr = int[5])  {//...}
}

stackalloc

在unsafe不安全环境中,我们可以通过stackalloc在堆栈上分配内存,因为在堆栈上分配的内存不受内存管理器管理,因此其相应的指针不需要固定。

static unsafe void Main(string[] args)
{
  int *ptr = stackalloc int[1] ;
}

2434C# 泛型(Generic)

在封装公共组件的时候,很多时候我们的类/方法不需要关注调用者传递的实体是"什么",这个时候就可以使用泛型。

比如:

using System;
using System.Web.Caching;

namespace Xy.CacheManager
{
  public class CacheHelper<T>
  {
      //获取缓存实体
      public static T Get(Cache cache,string cacheKey)
      {
        //....缓存操作
      } 
      //插入缓存
      public static void Set(Cache cache T tEntity,string cacheKey)
      {
        //....缓存操作
      }
  }
}

2433C# 泛型(Generic)

在声明泛型方法/泛型类的时候,可以给泛型加上一定的约束来满足我们特定的一些条件。

比如:

using System;
using System.Web.Caching;

namespace Demo.CacheManager
{
   public class CacheHelper<T> where T:new()
   {
      
   }
}

泛型限定条件:

  • T:结构(类型参数必须是值类型。可以指定除 Nullable 以外的任何值类型)
  • T:类 (类型参数必须是引用类型,包括任何类、接口、委托或数组类型)
  • T:new() (类型参数必须具有无参数的公共构造函数。当与其他约束一起使用时new() 约束必须最后指定)
  • T:<基类名> 类型参数必须是指定的基类或派生自指定的基类
  • T:<接口名称> 类型参数必须是指定的接口或实现指定的接口。可以指定多个接口约束。约束接口也可以是泛型的。
  • T:U

2432C# 事件(Event)

C# 这种事件—响应类比 Python 的信号和槽机制。同时,事件—响应的参数传递是默认的。委托定义好事件和响应函数的输入输出类型,然后事件的参数会自动传递给响应函数。
using System;

/***********发布器类***********/
public class EventTest
{
    public delegate void NumManipulationHandler(string name, int a); //声明委托
    public event NumManipulationHandler ChangeNum; //声明事件

    public void OpenDoor(string name, int a)//模拟事件
    {
        ChangeNum(name, a);  //事件触发
    }
}

/***********订阅器类***********/
public class subscribEvent
{
    public void result(string name, int a)
    {
        Console.WriteLine("{0} is arriving at Airport Terminal{1}", name, a);
    }
}

/***********触发***********/
public class MainClass
{
    public static void Main()
    {
        EventTest e = new EventTest(); /* 实例化事件触发对象 */
        subscribEvent v = new subscribEvent(); /* 实例化订阅事件对象 */

        /* 订阅器的printf()在事件触发对象中注册到委托事件中 */
        e.ChangeNum += new EventTest.NumManipulationHandler(v.result);
        e.OpenDoor("Yang", 3); /* 模拟事件 */
    }
}