---
title: "CSharp零碎知识点"
author: "Perrin Yong"
author_profile: https://www.pystone.net/profile/
published_by: "Perrin Yong"
canonical: https://www.pystone.net/notes/csharp-misc-tips/
type: note
content_role: unspecified
visibility: public
id_stability: rename-stable
source_path: "10-计算机、信息技术与工程/02-编程语言与运行时/.NET与CSharp/CSharp零碎知识点.md"
content_hash: 200da633b13601e47d3dafba9530013b51d97db741e431fa2efde5fc38de5e3a
knowledge_version: 224c990773de.5fa8af6e39fa
site_commit: 224c990773de166d23a886306577dd90379529ce
notes_commit: 5fa8af6e39fa3891d1b9b4832bfa6c4e0ecaaf0a
---
# CSharp零碎知识点

﻿# CSharp零碎知识点

> 创建时间：2020/6/8 10:59

## params

  1. 使用 params关键字可以指定一个方法参数,该方法参数的数目可变。
  2. 可以发送参数声明中所指定类型的逗号分隔的参数列表或指定类型的参数数组。 还可以不发送参数。 如果未发送任何参数，则 params 列表的长度为零
  3. 在方法声明中的 params 关键字之后不允许任何其他参数，并且在方法声明中只允许一个 params 关键字。

```csharp
string a = &quot;test&quot;;
string tmp = &quot;est&quot;;
string b = &quot;t&quot; + tmp;
Console.WriteLine(string .ReferenceEquals(str1, str2));

```

## 字符串前加@

@"C:\Program Files\Tencent\Tencent.exe "

在C#中”\“是转义符，所以当写"c:\xxx"时，C#会把”\“当成转义符。
加上@，C#就会将该字符串当作路径来处理，认成"c:\dos"

## Conditional 条件方法

利用 Conditional 属性，程序员可以定义条件方法。Conditional 属性通过测试条件编译符号来确定适用的条件。当运行到一个条件方法调用时，是否执行该调用，要根据出现该调用时是否已定义了此符号来确定。如果定义了此符号，则执行该调用；否则省略该调用（包括对调用的参数的计算）。

```csharp
string a = &quot;test&quot;;
string tmp = &quot;est&quot;;
string b = &quot;t&quot; + tmp;
Console.WriteLine(string .ReferenceEquals(str1, str2));

```

不论如何，该条件方法会被编译。
而在调用该方法的时候，如果相应的脚本定义了DEBUG`#define DEBUG`，则会执行TestConditional条件方法，如果没有定义，就不会执行。

## where

where的用法where 子句用于指定类型约束，这些约束可以作为泛型声明中定义的类型参数的变量。

### 接口约束

public class MyGenericClass<T> where T:IComparable { }

基类约束指出某个类型必须将指定的类作为基类（或者就是该类本身），才能用作该泛型类型的类型参数。 这样的约束一经使用，就必须出现在该类型参数的所有其他约束之前。

class MyClassy<T, U>
where T : class
where U : struct
{

}

### 构造函数约束

可以使用 new 运算符创建类型参数的实例；但类型参数为此必须受构造函数约束 new() 的约束。new() 约束可以让编译器知道：提供的任何类型参数都必须具有可访问的无参数（或默认）构造函数。
new() 约束出现在 where 子句的最后。
public class MyGenericClass <T> where T: IComparable, new()
{
// The following line is not possible without new() constraint:
T item = new T();
}

### 泛型方法与委托

public bool MyMethod<T>(T t) where T : IMyInterface { }
delegate T MyDelegate<T>() where T : new()

## ref和out的区别

  1. 两者都是按地址传递的，使用后都将改变知原来参数的数值。
  2. ref可以把参数的数值传递进函数，但是out是要把参数清空，就是说你无法把一个数值从out传递进去的道，out进去后，参数的数值为空，所以你必须初始化一次。这个就是两个的区别，或者说就像有的网友说的，ref是有进有出，out是只出不进。
  3. 使用ref型参数时，传入的参数必须先被初始版化。out，必须在方法中对其完成初始化。
  4. 使用ref和out时，在方法的参数和执行方法时，都要加Ref或Out关键字。以满足匹配。
  5. out适合用在需要retrun多个返回值的地方，而ref则用在需要被调用的方法修改调用者的引用的时候。
