C# 关键字/符号

where 泛型类型约束总结:

where T : struct 这表明T必须是一个值类型,像是int,decimal这样的

where T : class 这表明T必须是一个引用类型,像是自定义的类、接口、委托等

where T : new() 这表明T必须有无参构造函数,且如果有多个where约束,new()放在最后面

where T : [base class name] 这表明T必须是base class类获其派生类

where T : [interface name] 这表明T必须实现了相应的接口

参考:[C#]Where关键词的用法_六天-CSDN博客_c# where

C# 泛型 default()方法:

在泛型类和泛型方法中产生的一个问题是,在预先未知以下情况时,如何将默认值分配给参数化类型 T:

  • T 是引用类型还是值类型。
  • 如果 T 为值类型,则它是数值还是结构。

给定参数化类型 T 的一个变量 t,只有当 T 为引用类型时,语句 t = null 才有效;只有当 T 为数值类型而不是结构时,语句 t = 0 才能正常使用。解决方案是使用 default 关键字,此关键字对于引用类型会返回 null,对于数值类型会返回零。对于结构,此关键字将返回初始化为零或 null 的每个结构成员,具体取决于这些结构是值类型还是引用类型。对于可以为 null 的值类型,默认返回 System.Nullable,它像任何结构一样初始化。

参考:C# 泛型 default()方法 - 如.若 - 博客园

C# 关键符号:?

名称:可空类型修饰符。

引用类型可以使用空引用表示一个不存在的值,而值类型通常不能表示为空。

例如:

string str=null; //代码正确
int i=null; //代码错误,编译器报错

为了使值类型也可以赋空值,我们可以使用可空类型。

可控类型需要用可空类型修饰符"?“来表示,表现形式为"T?”

例如:

int? a;//表示可为空的整数
DateTime? b;//表示可为空的时间

此时,以下表达方式编译器就不报错了:

int? a=null;
DateTime? b=null;

T? 其实是System.Nullable(泛型结构)的缩写形式,也就意味着当你用到T?时编译器编译 时会把T?编译成System.Nullable的形式。

例如:int?,编译后便是System.Nullable的形式。

C# 关键符号:?:

名称:三元运算符

例如:a?b:c 表示如果表达式a为true,则返回b,否则返回c。这是省略if{}else{}的简单形式。

C# 关键符号:??

名称:空合并运算符

用于定义可空类型和引用类型的默认值。如果此运算符的左操作数不为null,则此运算符将返回左操作数,否则返回右操作数。

例如:a??b 当a为null时则返回b,否则返回a本身。

空合并运算符为右结合运算符,即操作时从右向左进行组合的。

例如:“a??b??c”的形式按“a??(b??c)”计算。

项目实例:

 ulong curHonor = (data.Param as ulong?) ?? 0;

C# 关键符号:?.

名称:NULL检查运算符

用于判断对象是否为空并获取对象的某个属性的值,可以代替if判断,简化代码。

例如:我们要根据userid查询username,常用的方式是:

string username="";
User user=new User();
//根据userid查询user实体(此步骤省略),然后取值
if(user!=null)
	username=user.username;

这个过程,可以简化为:

string username="";
User user=new User();
//根据userid查询user实体(此步骤省略),然后取值
username=user?.username;

从上面例子可以看出,基本的方法为:如果对象为NULL,则不进行后面的获取成员的运算,直接返回NULL。

global 关键字:

global它是全局访问修饰符,即所有对象都是完整路径表示

例如:Console.WriteLine();完整表示法:System.Console.WriteLine("ok");

那什么时候用global呢,实事上,之个关键字我们一般用的不多,只有在自定义类与系统类重名时才用的,看代码:

class Program
    {
        public class System { }
 
        static void Main(string[] args)
        { 
          global::  System.Console.WriteLine("ok");
      }
  }

我们看到了,program类中也有一个System类,我们知道System类是.net系统提供的,所以我们这时要用完整表示类:global:: System.Console.WriteLine("ok");否则会出错的!

#pragma warning disable

warning disable 作用:让编译器忽略指定编号的警告,跳过警告直接运行程序,可用来忽略一部分不重要的警告报错

项目示例:

pragma warning disable 0162

   private static void CheckMigrationStatus()
	{
        // 直接return代码,unity会报警告C0162
        return;
		try
		{
    		Callback();
		}
		catch (System.Exception e)
		{
			UnityEngine.Debug.LogError("WwiseUnity: Error during migration: " + e);
		}
	}
#pragma warning restore 0162

C# Activator和new的区别

1、你需要动态的创建一个实例模型的时候,就用Activator.CreateInstance(Type type);如果是明确的知道要创建哪个实例的模型,就可以用 new Class1()了。

T tInstance= (T)Activator.CreateInstance(typeof(T), new object[] { message });

2、基于接口的Remoting对象是不能用new来创建的,可以直接使用Activator来创建

3、C#中Activator.CreateInstance()方法用法分析。详情:

C#中Activator.CreateInstance()方法用法分析 - 如.若 - 博客园

4、.NET C# 三种实例化一个类的方式的性能比较。详情:

.NET C# 三种实例化一个类的方式的性能比较 - 船长&CAP - 博客园

总结:用 Activator 实例化一个类最快;其次是用 New 关键字;最慢的是用 Assembly 实例化。Activator 比 用 New 都快。

params的使用:

[原文]:Unity ref 和out、 params的使用_纸上得来终觉浅,绝知此事要躬行-CSDN博客

params是为动态数组而准备的

示例:

void Show(params int[] inVals)
{
    for (int i = 0; i < inVals.Length; ++i)
        Debug.Log(inVals[i]);
}
void Start()
{
    Show(1);
    Show(1, 2);
    Show(1, 2, 3);
}

我们直接输入数组的元素就行了,如果不加params,我们只能这样调用

 public void Getdd( int[] pp)
 {
      foreach (var p in pp)
      {
          print(p);
      }
 }
 
 void Start()
 {
      Getdd(new []{1,2,3});
 }

GetEnumerator() 和 foreach 的关系:

GetEnumerator() + MoveNext() + Current = foreach in

项目实例:

var e = mLobbyCmpDct.GetEnumerator();
while(e.MoveNext())
{
    e.Current.Value.ReInit(this);
}

Stack.peek() 和 Stack.pop() 的区别:

Stack.peek() 和 Stack.pop()的相同点是 获取栈顶的值,不同点 则是 Stack.peek()只是获取栈顶的值,而Stack.pop()是获取栈顶的值然后删除。

stack就这3个基本操作,push入栈,pop出栈,peek预览栈顶元素


未完待续.......

猜你喜欢

转载自blog.csdn.net/DeveloperZZW/article/details/121095255