《精通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#特性,因为涉及太多,忍痛略过,将来有机会在详谈.
《精通C#》自定义类型转化-扩展方法-匿名类型-指针类型(11.3-11.6)的更多相关文章
- C#3.0新特性:隐式类型、扩展方法、自动实现属性,对象/集合初始值设定、匿名类型、Lambda,Linq,表达式树、可选参数与命名参数
一.隐式类型var 从 Visual C# 3.0 开始,在方法范围中声明的变量可以具有隐式类型var.隐式类型可以替代任何类型,编译器自动推断类型. 1.var类型的局部变量必须赋予初始值,包括匿名 ...
- [Swift通天遁地]五、高级扩展-(3)日期和时间类型的扩展方法
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- dynamic动态类型的扩展方法
对于一个动态类型来说,你可以认为它包含任意成员,它们都能通过编译.但到了运行时,到底是否拥有这些成员,就真相大白了.如 dynamic test = ; Console.Write(test.Name ...
- 编写高质量代码改善C#程序的157个建议——建议101:使用扩展方法,向现有类型“添加”方法
建议101:使用扩展方法,向现有类型“添加”方法 考虑如何让一个sealed类型具备新的行为.以往我们会创建一个包装器类,然后为其添加方法,而这看上去一点儿也不优雅.我们也许会考虑修改设计,直接修改s ...
- typescript 添加基础类型的扩展方法
以时间转换为案例: //声明接口,也是在声明date这个基础类型要定义一个format的扩展方法,不写接口声明会报错 interface Date { Format(fmt:string):strin ...
- 040_字符串连接符 041_条件运算符目 042_运算符优先级_逻辑与或优先问题 043_自动类型转化 044_强制类型转换 045_基本类型常见错误_溢出_L问题
040_字符串连接符 package test_package; /** * 字符串运算符 * @author * */public class TestOperator05 { public sta ...
- 21扩展IEnumerable<T>泛型接口自定义LINQ的扩展方法
LINQ方法实际上是对IEnumerable<TSource>的扩展,如图: 本篇自定义一个MyWhere方法,达到与Where相同的效果. 使用LINQ自带的Where方法 ...
- Path类型的扩展方法 z
写了一个基于System.IO.Path类型方法的扩展类型,用于快速对文件系统路径进行操作.如下图: 其中有许多方法就是直接调用Path类型的静态方法.比如AppendPath方法内部会直接调用Pat ...
- Asp.net 面向接口可扩展框架之使用“类型转化基础服务”测试四种Mapper(AutoMapper、EmitMapper、NLiteMapper及TinyMapper)
Asp.net 面向接口可扩展框架的“类型转化基础服务”是我认为除了“核心容器”之外最为重要的组成部分 但是前面博文一出,争议很多,为此我再写一篇类型转化基础服务和各种Mapper结合的例子,顺便对各 ...
随机推荐
- Hibernate 基础配置及常用功能(二)
本章主要是描述几种经典映射关系,顺带比较Hibernate4.x和Hibernate5.x之间的区别. 一.建立测试工程目录 有关实体类之间的相互映射关系,Hibernate官方文档其实描述的非常详细 ...
- Dynamics AX 2012 在BI分析中建立数据仓库的必要性
AX系统已有的BI分析架构 对于AX 的BI分析架构,相信大家都了解,可以看Reinhard之前的译文[译]Dynamics AX 2012 R2 BI系列-分析的架构 . AX 的BI分析架构的优势 ...
- PHP 微信分享
share.php <?php //公众号设置一下 JS接口安全域名,不要http,www的一级域名,比如http://www.baidu.com域名下的某个路径要分享,js安全域名中只需填上 ...
- [转]opencv3.0 鱼眼相机标定
[原文转自]:http://blog.csdn.net/qq_15947787/article/details/51441031 前两天发表的时候没注意,代码出了点错误,所以修改了一下,重新发上来. ...
- 常用SQL总结
数据库知识总结一.数据库服务器设置1,查看数据库服务器编码 show variables like 'character%';2,设置数据库服务器编码 set character_set_ ...
- js禁止Backspace键使浏览器后退
在项目中遇到按下Backspace键让浏览器后退的问题,上网搜了几种解决方案都不太理想.于是集众人之智,采众家之长,归纳如下: 这里主要参考博客http://q821424508.iteye.com/ ...
- app里使用163邮箱发送邮件,被163认为是垃圾邮件的坑爹经历!_ !
最近有个项目,要发邮件给用户设定的邮箱报警,然后就用了163邮箱,代码是网上借来的^^,如下: package com.smartdoorbell.util; import android.os.As ...
- oracle 删除用户时的坑
ORACLE在使用 SELECT SID,SERIAL# FROM V$SESSION WHERE USERNAME='dt_zntg_trade' 删除会话时,一定要注意dt_zntg_trade的 ...
- selenium定位元素(本内容从https://my.oschina.net/flashsword/blog/147334处转载)
注明:本内容从https://my.oschina.net/flashsword/blog/147334处转载. 在使用selenium webdriver进行元素定位时,通常使用findElemen ...
- HANA SQL
约束 注释 你可以给你的 SQL 语句添加注释来增加可读性和可维护性. SQL 语句中注释的分隔如下: l 双连字符“--”.所有在双连字符之后直到行尾的内容都被 SQL 解析器认为是注释. l ...