《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)

1.类型转化在C#中有很多,常用的是int类型转string等,这些都有微软给我们定义好的,我们需要的时候直接调用就是了,这是值类型中的转化,有时候我们还会需要类类型(包括结构struct)的转化,还记得在继承中,子类可以隐式转化成父类,这是因为他们之间的继承关系。若是两个没有关系的类之间要进行转化的话就需要自定义类型转化。自定义的类型转化必须为静态类型,需要explicit关键字或者implicit关键字以及operator关键字格式大体上是:访问修饰符 static implicit/explicit operator 返回值类型(参数类型 oparam)。自定义类型转化的重点在于只要代码没错,就可以按你自己的想法对任何的不相干的类型进行转化。例:

namespace ExplicitAndImplicit
{
    class Program
    {
        static void Main(string[] args)
        {
            B b = new B(10);
            A a = (A)b;
           Console.WriteLine(a.ToString());
            Console.ReadLine();
        }
    }
    public struct A
    {
        public int W { get; set; }
        public int H { get; set; }
        public A(int w, int h) : this()
        {
            W = w;
            H = h;
        }
        public override string ToString()
        {
            return string.Format("W={0},H={1}",W,H);
        }
        public static explicit operator A(B b)
        {
            A a = new A();
            a.W = b.L * 2;
            a.H = b.L;
            return a;
        }
    }
    public struct B
    {
        public int L { get; set; }
        public B(int l) : this()
        {
            L = l;
        }
    }
}
结果:

可见转化是成功的。在转化时,返回值或者参数类型中必须要有一个是该封闭类。在例子中显示链接到了默认构造函数,书上说原因是如果结构使用了自动属性,所有的自定义构造函数必须显示调用默认构造函数,来初始化私有的后台字段,但是我在删除链接之后,结果依然,因而这个结论记住就好,若是遇到错误时刻添加试试,有人知道这是什么原因的话可以留言一起讨论。

2.扩展方法是在已经定义一个类,在不打算改变类的内部结构时或者无法派生时,在外部添加所需要的新需求的一种方法,在定义扩展方法的时候必须要定义在静态类中,因此,每个扩展方法也必须定义为静态类,其次就是在扩展方法时要将第一个参数用this进行修饰,要用this限定的参数表示被扩展的项,例:

static class Extensions

{

  public static int ReverseDigits(this int i)//this修饰参数,表示被扩展的项

{

  char[] digits=i.ToString().ToCharArray();//把int翻译为string然后获取所有字段

  Array.Reverse(digits);//反转数组中的项

  string newDigits=new String(digits);//返回string

  return int.Parse(newDigits);

}

}

 static void Main(string[] args)

{

  int digit=1234;

console.writeline(digit.ReverseDigits());

}

以上的例子我是写在同一个命名空间内,若是不在一个一个命名空间,则在调用扩展方法之前,需先引入扩展方法所在的命名空间。同时,我们还可以定义一个扩展方法,使只有正确的实现接口的类或者结构才可以使用。比如我们定义一个只有实现了IEnumerable<T>,才可以调用该扩展方法,例:

static class Extensions

{

public static void PrintItem(this system.collections.IEnumerable item)

{

 foreach(var i in item)

{

console.writeLine(i);

}

console.ReadLine();

}

}

 static void Main(string[] args)

{

  string[] s={"1","2","3","4"};

s.PrintItem();

}

3.匿名类型:有时候我们需要定义一个类来封装一些数据,都不需要任何的方法以及功能,并且这个类只有少量的方法会使用它,对于这样的类似于临时数据,我们如果特意封装一个类无疑是一种浪费,所以我们可以使用var关键字来定义一个匿名类型,定义方法和对象初始化器非常相识,只是在new与{}间的类名没有了,编译器会在编译时自动生成新的类的定义,初始化语法将会告诉编译器胃新建的类型创建私有的后台字段和只读属性。例如我们在项目中,我们时常会需要从数据库取出取数据,但是又不需要用到表格中的所有的字段,这个时候就是会用到匿名类型,这个方法在目前为止,我大部分和linq用在一起,很好用。匿名方法无法控制类型的名称,由编译器自己创建,自动基础object,它的字段以及属性都是只读的,不支持事件,自定义方法,自定义操作符和自定义重写,匿名类型是隐式封闭的,不可继承的,在创建实例是只能使用默认构造函数等都是它的限制。至于它的其余特性,可观看http://www.cnblogs.com/skykang/archive/2011/03/03/1970194.html的内容,这位作者写的很详细了。在我个人看来,使用匿名类型封装数据最好是在需要封装多种不同类型的数据时,以目前的经验来说,mvc中的model就是一个专门封装数据的类。

4.指针类型:在什么场合需要用到指针类型呢?一是在要绕过CLR管理直接操作指针已优化应用程序的特定部分,二是要调用基于C的dll或调用需要指针作为参数的COM服务器。但是即使在这种情况下也可以使用system.InPtr类型和System.Runtime.InteropServices.Marshal类型的成员,而不使用指针类型。要使用指针就需要通过项目支持不安全代码,我们不仅需在开发环境中设置允许不安全代码以外,还需要使用unsafe关键字特别声明一个代码区域,可以使用*操作符构建数据类型的指针,使用&操作符获取被指向的内存地址,使用->访问公共成员,但是也可以使用(*)来解除指针的引用,使其也可以使用点操作符访问字段,例:

struct Point

{

public int x;

public int y;

public override string Tostring()

{

return string.Format("({0},{1})",x,y);

}

}

unsafe static void UsePointerToPoint()

{

//通过指针访问成员

Point point;

Point* p=&point;

p->x=100;

p->y=200;

console.writeline(p->Tostring());

//通过指针间接寻址访问成员

Point point2;

Point* p2=&point2;

(*p2).x=100;

(*p2).y=200;

console.writeline(p->Tostring());

}

对指针这个C#特性,因为涉及太多,忍痛略过,将来有机会在详谈.

 

转载于:https://www.cnblogs.com/Lin-Li/p/5974329.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值