.NET 关键字
一、base关键字
可以通过base关键字访问上一级父类方法的访问。静态static函数无法调用base
二、new 关键字new
new有2个作用。
new运算符 用来分配内存空间和初始化对象。
new修饰符 微软官方说明:可以显式隐藏从基类继承的成员,该成员的派生版本将替换基类版本。(以前一直不在乎这种场合,因为编译器就提示警告)他和overrider有什么区别呢?
/// <summary>
/// 关键字
/// </summary>
public class KeywordA
{ public KeywordA()
{
Name = "apple";
}
public string Name { get; set; } public virtual void Test()
{
Console.WriteLine("KeywordA.Test()" + Name);
} public void Test1()
{
Console.WriteLine("KeywordA.Test1()" + Name);
}
} public class KeywordB : KeywordA
{
public KeywordB()
{
Name = "button";
}
public new string Name { get; set; }
public new void Test()
{
Console.WriteLine("KeywordB.Test()" + Name);
base.Test();
} public new void Test1()
{
Console.WriteLine("KeywordB.Test1()" + Name);
base.Test1();
}
} public class KeywordC : KeywordA
{
public KeywordC()
{
Name = "city";
} public override void Test()
{
Console.WriteLine("KeywordC.Test()"+Name);
base.Test();
}
}
static void Main(string[] args)
{
KeywordA a = new KeywordA();
a.Test();
a.Test1();
Console.WriteLine("=========================");
KeywordB b = new KeywordB();
b.Test();
b.Test1();
a = new KeywordB();
a.Test();
a.Test1();
Console.WriteLine("=========================");
KeywordC c = new KeywordC();
c.Test(); a = new KeywordC();
a.Test();
a.Test1();
Console.WriteLine("=========================");
Console.ReadKey();
}
通过以上代码执行得出以下结果:
KeywordA.Test()apple
KeywordA.Test1()apple
=========================
KeywordB.Test()button
KeywordA.Test()apple
KeywordB.Test1()button
KeywordA.Test1()apple
KeywordA.Test()apple
KeywordA.Test1()apple
=========================
KeywordC.Test()city
KeywordA.Test()city
KeywordC.Test()city
KeywordA.Test()city
KeywordA.Test1()city
=========================
1.new 只是个修饰符,看IL代码和不加NEW的方法一样。都叫覆盖。为了减少warn,建议加把。
2.虚方法、实方法都可以被覆盖(new),抽象方法,接口 不可以。
3.不管是重写还是覆盖都不会影响父类自身的功能。
4.当用子类创建父类的时候,如 A c = new B(),重写会调用子类的功能;而覆盖不会,仍然调用父类功能。
三、abstract 修饰符 abstract关键字
关于virtual 虚方法和抽象方法 、抽象类网上资料太多了。也非常好区分。abstract继承类必须实现抽象定义。而virtual 可以选择是否重写基类虚方法。 这里就摘录微软的定义了:
abstract 修饰符指示所修饰的内容缺少实现或未完全实现。
abstract 修饰符可用于类、方法、属性、索引器和事件。
标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
抽象类具有以下特性:
抽象类不能实例化。
抽象类可以包含抽象方法和抽象访问器。
不能用 sealed(C# 参考) 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。
四、virtual 修饰符
virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
除了声明和调用语法不同外,虚拟属性的行为与抽象方法一样。
在静态属性上使用 virtual 修饰符是错误的。
通过包括使用 override 修饰符的属性声明,可在派生类中重写虚拟继承属性。
五、const / readonly
都是只读的意思。表面上看区别在于const首次赋值后就不可以改了,而readonly在初始化类后就不能修改了。
public class Keyword2
{ public static string Name_static = "Name_static"; public readonly string Name_readonly = "Name_readonly"; public const string Name_const = "Name_const"; public static readonly string Name_static_readonly = "Name_static_readonly"; public Keyword2(string text="Init")
{
Name_static = "Name_static_" + text;
Name_readonly = "Name_readonly_" + text;
//Name_const = "Name_const" + text;
//Name_static_readonly = "Name_static_readonly" + text; } }
static void Main(string[] args)
{
//DoKeyword1();
DoKeyword2(); Console.ReadKey();
} /// <summary>
/// const readonly
/// </summary>
private static void DoKeyword2()
{
Console.WriteLine("========初始化字段=================");
Console.WriteLine(Keyword2.Name_const);
Console.WriteLine(Keyword2.Name_static);
Console.WriteLine(Keyword2.Name_static_readonly); Console.WriteLine("========初始化构造函数=================");
Keyword2 kw = new Keyword2();
Console.WriteLine(kw.Name_readonly);
Console.WriteLine(Keyword2.Name_const);
Console.WriteLine(Keyword2.Name_static);
Console.WriteLine(Keyword2.Name_static_readonly); Console.WriteLine("========修改内容=================");
//Keyword2.Name_const = Keyword2.Name_const+"_Edit";
//Keyword2.Name_static_readonly = Keyword2.Name_static_readonly + "_Edit";
//kw.Name_readonly = Keyword2.Name_readonly + "_Edit";
Keyword2.Name_static = Keyword2.Name_static + "_Edit";
Console.WriteLine(Keyword2.Name_static);
}
IL代码:
.class public auto ansi beforefieldinit 关键字使用和执行顺序.Keyword2
extends [mscorlib]System.Object
{
// Fields
.field public static literal string Name_const = "Name_const"
.field public static string Name_static
.field public initonly string Name_readonly
.field public static initonly string Name_static_readonly // Methods
.method public hidebysig specialname rtspecialname
instance void .ctor (
[opt] string text
) cil managed
{
.param [] = "Init"
// Method begins at RVA 0x2156
// Code size 54 (0x36)
.maxstack IL_0000: ldarg.
IL_0001: ldstr "Name_readonly"
IL_0006: stfld string 关键字使用和执行顺序.Keyword2::Name_readonly
IL_000b: ldarg.
IL_000c: call instance void [mscorlib]System.Object::.ctor()
IL_0011: nop
IL_0012: nop
IL_0013: ldstr "Name_static_"
IL_0018: ldarg.
IL_0019: call string [mscorlib]System.String::Concat(string, string)
IL_001e: stsfld string 关键字使用和执行顺序.Keyword2::Name_static
IL_0023: ldarg.
IL_0024: ldstr "Name_readonly_"
IL_0029: ldarg.
IL_002a: call string [mscorlib]System.String::Concat(string, string)
IL_002f: stfld string 关键字使用和执行顺序.Keyword2::Name_readonly
IL_0034: nop
IL_0035: ret
} // end of method Keyword2::.ctor .method private hidebysig specialname rtspecialname static
void .cctor () cil managed
{
// Method begins at RVA 0x218d
// Code size 21 (0x15)
.maxstack IL_0000: ldstr "Name_static"
IL_0005: stsfld string 关键字使用和执行顺序.Keyword2::Name_static
IL_000a: ldstr "Name_static_readonly"
IL_000f: stsfld string 关键字使用和执行顺序.Keyword2::Name_static_readonly
IL_0014: ret
} // end of method Keyword2::.cctor } // end of class 关键字使用和执行顺序.Keyword2
总结:
1.const 它也是静态的。
2.Name_readonly 在编译时自动将赋值写入构造函数,完成初始化值。
3.初始化顺序是 先 const-> static ->构造函数。
六、volatile 修饰符
七、in/out 泛型修饰符
说得直白点就是泛型类型的类型转换。
out “子类”向“父类”转换,即泛型接口的协变
in “父类”向“子类”转换,即泛型接口的逆变
目前我已知的类库中 泛型枚举接口 ,还有泛型委托都已经改成协变逆变了。
public interface IEnumerable<out T> : IEnumerable
public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
public delegate void Action<in T>(T obj);
案例1 IEnumerable<out T>使用
public static void 泛型类型转换()
{ // 普通的类型转换
Animal animal = new Dog(); //类型的隐式转换
Dog dog = (Dog)animal; //类型的强制转换 // 泛型的类型转换
IEnumerable<Animal> iAnimal = null;
IEnumerable<Dog> iDog = null;
//// “子类”向“父类”转换,即泛型接口的协变 out
iAnimal = iDog;
// “父类”向“子类”转换,即泛型接口的逆变 in ,
//由于IEnumerable没有提供IEnumerable<in T>,所以编译时出错
iDog = iAnimal;
} public class Animal
{
}
public class Dog : Animal
{
}
案例2 实际场景中遇到的协变
一般场景,用协变的机会会多点。
有2个继承关系的类。
基类是 RoomInfoVModel房间信息相关的VO1.
它的子类RoomInfoPriceConvertVModel用来计算价格的VO2.
因为VO2主要是参与价格计算最终生成实际价格会放入到VO1,我不想让VO1太过臃肿。
那么在以下方法中,我从DB中获取到VO2List如何返回VO1List
我原先用了方法2:遍历集合吧对象逐个进行类型转换。
现在换成方法1了。IList<> 没有提供in out 功能,又懒得去扩展ILIST。
所以就使用 public delegate TOutput Converter<in TInput, out TOutput>(TInput input);转换了。
/// <summary>
/// 根据入住日期获取房型价格列表
/// </summary>
/// <param name="req"></param>
/// <returns></returns>
public IList<RoomInfoVModel> GetCustomerRoomPrices(HashRequest req)
{
var discountName = req.GetString("discoutname");
var bIsMustExistsRoom = req.GetBoolean("IsMustExistsRoom");
var inDate = req.GetString("inDate");
var exitDate = req.GetString("ExitDate");
Sql sql = new Sql();
sql.Append(""); var models = Repo.Fetch<RoomInfoPriceConvertVModel>(sql.SQL, sql.Arguments); ConvertPrices(discountName, inDate, models); // 1、通过逆变
return models.ConvertAll<RoomInfoVModel>((input) => input);
// 2.遍历集合吧对象逐个进行类型转换
//return models.Select(a => a as CustomerHotelInfoVModel).ToList();
// 3.对象属性自动映射
//return AutoMapper.Mapper.Map<List<CustomerHotelInfoVModel>>(models); }
最后,其他修饰符会在后期文章中结合具体内容出现,比如async , params。
.NET 关键字的更多相关文章
- 作为一个新手的Oracle(DBA)学习笔记【转】
一.Oracle的使用 1).启动 *DQL:数据查询语言 *DML:数据操作语言 *DDL:数据定义语言 DCL:数据控制语言 TPL:事务处理语言 CCL:指针控制语言 1.登录 Win+R—cm ...
- JavaScript var关键字、变量的状态、异常处理、命名规范等介绍
本篇主要介绍var关键字.变量的undefined和null状态.异常处理.命名规范. 目录 1. var 关键字:介绍var关键字的使用. 2. 变量的状态:介绍变量的未定义.已定义未赋值.已定义已 ...
- java面向对象中的关键字
1,super关键字 super:父类的意思 1. super.属性名 (调用父类的属性) 2. super.方法名 (调用父类的方法) 3. super([参数列表])(调用父类的构造方法) 注意: ...
- 关于javascript中的this关键字
this是非常强大的一个关键字,但是如果你不了解它,可能很难正确的使用它. 下面我解释一下如果在事件处理中使用this. 首先我们讨论一下下面这个函数中的this关联到什么. function doS ...
- transient关键字的用法
本篇博客转自 一直在路上 Java transient关键字使用小记 1. transient的作用及使用方法 我们都知道一个对象只要实现了Serilizable接口,这个对象就可以被序列化,Java ...
- Java关键字:static
通常,当创建类时,就是在描述那个类的外观和行为.只有用new创建类的对象时,才分配数据存储空间,方法才能被调用.但往往我们会有下面两种需求: 1.我想要这样一个存储空间:不管创建多少对象,无论是不创建 ...
- Core Java 总结(关键字,特性问题)
2016-10-19 说说&和&&的区别 初级问题,但是还是加入了笔记,因为得满分不容易. &和&&都可以用作逻辑与的运算(两边是boolean类型), ...
- Net中的常见的关键字
Net中的关键字有很多,我们最常见的就有new.base.this.using.class.struct.abstract.interface.is.as等等.有很多的,在这里就介绍大家常见的,并且有 ...
- php多关键字查询
php单一关键字查询 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 tdansitional//EN" "http: ...
- Keil> 编译器特有的功能 > 关键字和运算符 > __weak
__weak 此关键字指示编译器弱导出符号. 可以将 __weak 关键字应用于函数和变量声明以及函数定义. 用法 函数和变量声明 对于声明,此存储类指定一个 extern 对象声明,即使不存在,也不 ...
随机推荐
- Python Backup Files
近来书写 Python 脚本进行替换以前的 shell 脚本,发现 Python 优于 shell 的最直观的一点Python 结构明了,可读性高(本人认为)在此做一些记录 本次记录利用 Python ...
- 使用EntityFramework6完成增删查改和事务
使用EntityFramework6完成增删查改和事务 上一节我们已经学习了如何使用EF连接数据库,并简单演示了一下如何使用EF6对数据库进行操作,这一节我来详细讲解一下. 使用EF对数据库进行操作, ...
- OpenXml 入门----OpenXml Tools使用技巧
简介: Office2007以上版本的文档其实可以转换为XML格式.截图如下: Test.doc 解压过后已经完全变为文件夹和xml文件,文档的属性和信息都存储在了xml里面.根据XML就封装出了Op ...
- Adaboost 卡口车辆检测训练
之前做了SVM的车脸检测,主要是针对车脸,接下来尝试利用Adaboost和Haar进行车脸的检测.我利用的主要是opencv中的cascade,其已经把Adaboost相关的算法做成了exe,直接调用 ...
- win8程序开机自启动管理
主要介绍利用系统自身的工具来管理开机自启动,而非第三方的工具,自己了解了,也写出来分享给大家@.·.@ 1.程序设置开机自启动 a. 打开计算机资源管理器-->进入"C:\Progra ...
- hdu-5521 Meeting(最短路)
题目链接: Meeting Time Limit: 12000/6000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) ...
- WPF数字输入框和IP地址输入框
数字输入框 简介 在业务中,我们经常需要限制用户的输入,比如限制输入长度,限制只能输入数字等等.限制输入长度WPF内置的TextBox已经帮我们解决了,但是限制输入数字却并未在WPF中内置解决方案.使 ...
- java 14 -1 正则表达式
正则表达式:符合一定规则的字符串. 1.判断QQ号码是否正确的案例: public class RegexDemo2 { public static void main(String[] args) ...
- c#解决窗体假死的一种方法
public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_C ...
- poj 2245 Lotto
Lotto Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6806 Accepted: 4298 Description ...