一:值类型/引用类型的区别

值类型主要包括简单类型,枚举类型,和结构体类型等,值类型的实例通常被分配在线程堆栈上面变量保存的内容是实例数据本身。引用类型被分配在托管堆上,变量保存的是地址。引用类型主要包括类类型,接口类型,委托类型和字符串类型等。

关于参数传递,这里有四种:

值类型参数的按值传递;

引用类型参数按值传递;

关于string引用类型参数按值传递的特殊情况;虽然string类型也是引用类型,然而在按值传递时,传递的实参却不会因方法中形参的改变而被修改。

    class Program
{
static void Main(string[] args)
{
Console.WriteLine("String引用类型按值传递的特殊情况");
string str = "old string"; //引用类型
ChangeStr(str);
Console.WriteLine("调用之后的值:"+str);
Console.ReadKey();
} private static void ChangeStr(string oldStr)
{
oldStr = "New string";
Console.WriteLine("方法中的oldStr:"+oldStr);
}
}

造成这个原因是由于:string具有不变性,一旦一个string类型被赋值,则它是不会改变的,即不能通过代码来修改它的值,图中好像是对str进行了修改,但是由于string类型的不可变性,系统会重新分配一块内存空间来存放New string字符串。把修改的内存首地址赋值给oldStr变量,所以值就发生了变化。

值类型参数的按引用传递;

引用类型参数的按引用传递;

这里就需要使用到ref,out这两个关键字了,他们是把值类型和引用类型都按照引用进行传递。

二:重新认识------泛型

泛型(generic):就是通用类型,它可以代替任意的数据类型,是类型参数化,从而达到只实现一个方法就可以操作多种数据类型的目的。泛型将方法实现行为和方法操作的数据类型分离,实现代码的重用。

            //用int作为实际参数来初始化泛型类型
List<int> inList=new List<int>();
inList.Add(3);
//用string作为实际参数来初始化泛型类型
List<string> inString=new List<string>();
inString.Add("ahui");

上面的就是泛型,List<T>是.NET类库中实现的泛型类型,T是泛型参数(形参),想实例化一个泛型类型,就必须传入实际的类型参数。

    /// <summary>
/// 定义一个泛型---比较各种类型的大小。 IComparable接口是因为里面有个CompareTo方法
/// </summary>
/// <typeparam name="T">泛型的参数,就是传递来的类型</typeparam>
public class Compare<T> where T:IComparable
{
public static T CompareGeneric(T t1,T t2)
{
if (t1.CompareTo(t2)>0)
{
return t1;
}
else
{
return t2;
}
}
}

这里面的T就是我们将来调用方法时往里面传递的类型(泛型的类型参数)。CompareGeneric是实现泛型的方法,代码中的where语句是类型参数的约束,它用来使类型参数可以适用于CompareTo方法。从而对类型参数进行约束。

            //调用泛型,直接点操作就可以来,只需要注意传递进去的类型就可以。
Console.WriteLine(Compare<int>.CompareGeneric(1,2));
Console.WriteLine(Compare<string>.CompareGeneric("2222","111"));
Console.ReadKey();

1:泛型除了可以实现代码的重用,还提供了更好的性能和类型安全特性。

2:使用泛型可以减少装箱和拆箱带来的性能消耗。因为我们直接就是类型,不需要在将其转换为object类型再来进行操作。

3:泛型代码中,T就是类型参数,无论调用类型方法还是初始化泛型实例,都需要用真实类型代替T。

4:我们有的时候不需要给T赋值,编译器自己可以推测出T是什么类型的,这是类型参数的推断。(参数只能是一种类型)

5:类型参数的约束:

共有4中约束,语法类似:约束要放在泛型方法或类型声明的末尾,并且要使用where关键字。

--->引用类型约束

引用类型约束的表示形式为T:class,它确保传递的类型实参必须是引用类型。

    /// <summary>
/// 引用类型约束
/// </summary>
/// <typeparam name="T"></typeparam>
public class Samplereference<T>where T:Stream
{
public void Test(T stream)
{
stream.Close();
}
}

类型参数T设置了引用类型约束。where T:stream的意思就是告诉编译器,传递的类型必须是System.IO.Stream或者是其子类。

--->值类型约束

表示形式:T:struct

    /// <summary>
/// 值类型约束
/// </summary>
/// <typeparam name="T"></typeparam>
public class Samplevaluetype<T> where T:struct //约束为结构体了,(值类型)
{
public static T Test()
{
return new T(); //T是一个值类型,所有的值类型都有一个公共的无参构造函数,
}
}

--->构造函数类型约束

表示形式:T:new(),若是有多个约束此约束应该最后指定。

--->转换类型约束

表示形式:T:基类名。T:接口名或T:U;

---->组合约束

就是将上面的都组合在一起,类必须放在接口前面,不同的类型参数可以有不同的约束,但每种类型参数必须分别使用一个单独的where关键字。

三:可空类型

可空类型也是值类型,但它包含null值的值类型,

    int? a=null;

int ?就是可空的int类型,?修饰符只是C#的语法糖,就是C#提供的一种方便的表示形式。

四:空合并操作符(??)

??操作符,它会对左右两个操作数进行判断,如果左边的数不为null,就返回左边的数。如果左边的数为Null,就返回右边的数。主要用于可空类型,也可以用于引用类型的判空,但是不能用于值类型。

        /// <summary>
/// ??运算符
/// </summary>
private static void NullcoalescingOperator()
{
int? nullable = null;
int? nullhasvalue = 1; int x = nullable ?? 12; //和三目运算符功能一样。
int y = nullhasvalue ?? 123;
Console.WriteLine("可空类型没有值:"+x);
Console.WriteLine("可空类型有值:" + y); Console.WriteLine();
//??运于引用类型
string stringnotnull = "123";
string stringisnull = null;
string result = stringnotnull ?? "456";
string result2 = stringisnull ?? "12";
Console.WriteLine("引用类型不为Null的情况:"+result);
Console.WriteLine("引用类型为Null的情况:" + result2);
}
        static void Main(string[] args)
{
            Console.WriteLine();
NullcoalescingOperator();
Console.ReadKey();
        }

使用??运算符可以很方便地设置默认值,避免了通过if,else语句来进行判断,从而简化了代码行数,提高了代码的可读性。

五:匿名方法

解释:就是没有名字的方法,因为没有名字,匿名方法只能在函数定义(就是把方法的定义和实现嵌套在一起)的时候被用。其它任何 情况下都不能被调用。

委托是匿名函数的前提。

    public class Friend
{
/// <summary>
/// 实现委托的方法(就是委托要传递的方法)
/// </summary>
/// <param name="nickName"></param>
public void Vote(string nickName)
{
Console.WriteLine("昵称为:{0},来了呀",nickName);
}
}
    class Program
{
//定义委托
private delegate void VoteDelegate(string name); private static void Main(string[] args)
{
//实例化委托对象
VoteDelegate voteDelegate = new VoteDelegate(new Friend().Vote); //Vote方法当作了参数来传递。
voteDelegate("ahui"); //把ahui传递到了下面的方法中。
Console.ReadKey();
}
}

下面是使用匿名函数

   class Program
{
//定义委托
private delegate void VoteDelegate(string name); private static void Main(string[] args)
{
//使用匿名函数来实例化委托。必须为delegate。其余就和方法的一样。
VoteDelegate voteDelegate = delegate(string nickName)
{
Console.WriteLine("昵称为:" + nickName);
};
//通过调用委托来回调Vote()方法,这是隐式调用方式。
voteDelegate("ahui");
Console.ReadKey();
}
}

我们使用匿名函数就不需要单独定义一个Vote方法,这减少了代码行数。

匿名函数的缺点:

不能被其他地方调用,容易形成闭包。

30天C#基础巩固-----值类型/引用类型,泛型,空合并操作符(??),匿名方法的更多相关文章

  1. 数往知来C#之接口 值类型与引用类型 静态非静态 异常处理 GC垃圾回收 值类型引用类型内存分配<四>

    C# 基础接口篇 一.多态复习 使用个new来实现,使用virtual与override    -->new隐藏父类方法 根据当前类型,电泳对应的方法(成员)    -->override ...

  2. C# 构造基础返回值类型-BaseResponse

    学无止境,精益求精 十年河东,十年河西,莫欺少年穷 用于基础返回值类型,如下: using System; using System.Collections.Generic; using System ...

  3. c#1所搭建的核心基础之值类型和引用类型

    这个主题很重要,在.NET中做的一切其实都是在和一个值类型或者引用类型打交道. 现实世界中的值和引用 假定你在读一份非常棒的东西,希望一个朋友也去读他.于是你到复印室里复印了一份.这个时候他获得了属于 ...

  4. js的基础(平民理解的执行上下文/调用堆栈/内存栈/值类型/引用类型)

    与以前的切图比较,现在的前端开发对js的要求似乎越来越高,在开发中,我们不仅仅是要知道如何运用现有的框架(react/vue/ng), 而且我们对一些基础的知识的依赖越来越大. 现在我们就用平民的方法 ...

  5. C#面试基础知识点:值类型和引用类型(1)(填坑文)

    目录 前言 C#值类型和引用类型 基类(共同点) 值类型继承基类(不同点) 应用类型继承 技术经理的问题 值类型与引用类型都可以用Equals来比较吗? 如何将一个数组a的值赋予数组b然后对b做修改而 ...

  6. C#基础:值类型、引用类型与ref关键字

    在C#中,ref的意思是按引用传递.可以参考C++: int a = 10, b = 20; void swap(int x, int y) { int temp = x; x = y; y = te ...

  7. 深入C#内存管理来分析值类型&引用类型,装箱&拆箱,堆栈几个概念组合之间的区别

    C#初学者经常被问的几道辨析题,值类型与引用类型,装箱与拆箱,堆栈,这几个概念组合之间区别,看完此篇应该可以解惑. 俗话说,用思想编程的是文艺程序猿,用经验编程的是普通程序猿,用复制粘贴编程的是2B程 ...

  8. JAVASCRIPT数据类型(值类型-引用类型-类型总览)

    值类型:也称为原始数据或原始值(primitive value). 这类值存储在栈(stack)中,栈是内存中一种特殊的数据结构,也称为线性表,栈按照后进先出的原则存储数据,先进入的数据被压入栈底,最 ...

  9. 6个重要的.NET概念:栈,堆,值类型,引用类型,装箱,拆箱

    引言 本篇文章主要介绍.NET中6个重要的概念:栈,堆,值类型,引用类型,装箱,拆箱.文章开始介绍当你声明一个变量时,编译器内部发生了什么,然后介绍两个重要的概念:栈和堆:最后介绍值类型和引用类型,并 ...

随机推荐

  1. 可在广域网部署运行的QQ高仿版 -- GG叽叽V3.5,增加自拍头像功能、细节优化(源码)

    距离上次发版本(GG叽叽V3.4,增加系统设置.最近联系人.群功能)又有1个月了,在这个月内,由于空闲时间不是很多,所以,GG增加的主要功能只是拍照并设定其为自己头像.修改密码.删除好友.以及一些bu ...

  2. Linux及文件系统基本介绍

    Linux及文件系统基本介绍 1   互联网行业现状 在服务器端市场: 超级计算机 2014年11月的数据显示前500系统中的485个系统都在运行着 Linux 的发布系统,而仅仅只有一台运行着 Wi ...

  3. ASP.NET MVC请求处理管道生命周期的19个关键环节(1-6)

    ASP.NET和ASP.NET MVC的HttpApplication请求处理管道有共同的部分和不同之处,本系列将体验ASP.NET MVC请求处理管道生命周期的19个关键环节. ①以IIS6.0为例 ...

  4. 使用ACE遇到无法打开包括文件:“inttypes.h”的解决方案

    本来想使用ACE_Get_Opt类来做一个命令行解析的功能,但是当项目中配置好了ACE库的路径后,编译时遇到"无法打开包括文件: inttypes.h : No such file or d ...

  5. DDD领域驱动设计实践篇之如何提取模型

    需求说明: 省级用户可以登记国家指标 省级用户和市级用户可以登记指标分解 登记国家指标时,需要录入以下数据:指标批次.文号.面积,这里省略其他数据,下同 登记指标分解时,需要录入以下数据:指标批次.文 ...

  6. MVVM架构~knockoutjs实现简单的购物车

    返回目录 概念相关 购物车相信大家都用过,很方便,可以将多个商品添加到购物车,并且可以修改购买商品的数据,当然为了用户体验好,在修改数据时,你的价格也会出现变化的,这使用JS可以实现,但我认为,代码量 ...

  7. 你可能不知道console强大

    写在前面 大家都有用过各种类型的浏览器,每种浏览器都有自己的特色,本人拙见,在我用过的浏览器当中,我是最喜欢Chrome的,因为它对于调试脚本及前端设计调试都有它比其它浏览器有过之而无不及的地方.可能 ...

  8. 用css3实现各种图标效果(2)

    写在前面 写的一模一样的css样式,结果却导致原来出来不一样的效果图. 用chrome的开发者工具查看,比较起来还是一模一样的css样式,可为什么会出现不一样的placeholder效果呢?一个白色粗 ...

  9. angularjs的resource实例对象

    angularjs的resource实例对象 我们看看都有啥 而直接使用service对象的时候没有前面这些$

  10. Mybatis中SqlMapper配置的扩展与应用(2)

    三.子表删除兼容问题 这个问题,使用SQL配置函数不太好处理,而且就算使用SQL配置函数,也不够直观,有点自动生成SQL的意味,太Hibernate了(不过要是可以兼收Hibernate和Mybati ...