.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 对象声明,即使不存在,也不 ...
 
随机推荐
- sql 执行动态语句
			
没看明白,可不可以描述清楚点哦 收获园豆:5 回复 | artwl | 专家六级 |园豆:16486 | 2011-09-01 09:10 exec (select top 2 * from pub ...
 - 一个自定义 HBase Filter -“通过RowKeys来高性能获取数据”
			
摘要: 大家在使用HBase和Solr搭建系统中经常遇到的一个问题就是:“我通过SOLR得到了RowKeys后,该怎样去HBase上取数据”.使用现有的Filter性能差劲,网上也没有现成的自定义Fi ...
 - oracle11G在linux环境下的卸载操作
			
1.使用SQL*PLUS停止数据库[oracle@OracleTest oracle]$ sqlplus logSQL> connect / as sysdbaSQL> shutdown ...
 - [转]Worksheet.Change Event (Excel)
			
本文转自:https://msdn.microsoft.com/en-us/library/office/ff839775.aspx#AboutContributor Example The fo ...
 - 边工作边刷题:70天一遍leetcode: day 71
			
Longest Substring with At Most Two Distinct Characters # Given a string, find the length of the long ...
 - POJ 3150 Cellular Automaton --矩阵快速幂及优化
			
题意:给一个环,环上有n块,每块有个值,每一次操作是对每个点,他的值变为原来与他距离不超过d的位置的和,问k(10^7)次操作后每块的值. 解法:一看就要化为矩阵来做,矩阵很好建立,大白书P157页有 ...
 - bootstrap学习总结-js组件(四)
			
这次我们来看下js组件的使用,本篇文章会有点长,希望大家可以耐心看,相信收获会有不少.不少园友加我好友,表示喜欢我写文字的风格,简单明了,这里,再次谢谢你们的支持.一方面,博主自身技术有限,写的东西都 ...
 - ZGrapher 画函数曲线图的工具
			
可以下载个绿色版,我下载的是 ZGrapher 1.4 绿色版.下面先看下图出来的图: 然后可以在“file"->"Save as Picture ..." -&g ...
 - [原创]  NetBean开发c++程序指南1- 加入c++项目文件夹
			
利用 NetBean开发c/c++程序,导入原有程序代码. 1. 在菜单栏的 "工具" -> 选项 -> c/c++开发 如果彩色就是激活的状态,否则选择激活. 2. ...
 - iOS app上传错误集锦(转载)
			
1.工程里增加了版本自动更新. 2.未增加判断网络状态的类Reachability. 3.问题:error itms -90049 This bundel is invalid. The bundle ...