cat
Shioho

# 特性

# System

# [Flags]

Flags 关键字使该枚举可进行位运算,可以让一个枚举类型中包含多个该枚举类型的值

假如有类型

[Flags]
    public enum Show
    {
        A = 0x00000001,
        B = 0x00000010,
        C = 0x00000100,
        D = 0x00001000,
    }

合并多个,使用 |

Show show=Show.A | Show.B

判断是否存在某个值

Show show=Show.A | Show.B;
  show.HasFlag(Show.A);
  // 其他
  bool 包含=(show & Show.A)!=0;

去掉一个值

Show show=Show.A | Show.B;
 show=show & (~Show.A);

取反一个值

Show show=Show.A | Show.B;
  bool 包含=(show & Show.A)!=0;
  if(包含)
  {
     show=show & (~Show.A);
  }
  else
  {
     show=show | Show.A;
  }

# System.ComponentModel

# [Description]

通常用于枚举的描述

public enum Pepole
{
  [Description("男孩")]
  boy=1,
  [Description("女孩")]
  girl=2,
}

可通过以下方法获取描述值

Pepole pepole = Pepole.boy;
var des = pepole as DescriptionAttribute;
string value = des.Description;

循环遍历获取

foreach (var value in Enum.GetValues(typeof(Pepole)))
{
      var fieldInfo = value.GetType().GetField(value.ToString());
      var attribArray = fieldInfo.GetCustomAttributes(false);
      var attrib = attribArray[0] as DescriptionAttribute;
      var des = des.Description;
}

# 类型转化

# 隐式类型重载

可以将 B 类隐式转化为 A 类,如 float aaa=1.1,MyClass mc = aaa;

public static implicit operator A(B b)
        {
            return new A();
        }

# 字符串相关

# StringBuilder

# 变量和固定文本输入

StringBuilder sb = new StringBuilder();
sb.Append($"{我是变量}我是固定文本");

# 判断字符串是否以 xxx 结尾

string a = "xxxxx";
bool isEndWithXXX = a.EndsWith("xxx");

# 序列化相关

# 某个类序列化为二进制写入文件中

FileStream fs = new FileStream("写入文件路径",FileMode.Create,FileAccess.ReadWrite,FileShare.ReadWrite);
BinaryFormatter bf = new BinaryFormatter();
// 序列化
bf.Serialize(fs,要转化成二进制的数据内容);
fs.Close();

反序列化过程与上类似,先加载二进制数据,在通过 bf.Deserialize (xxx) 获得该类

MemoryStream stream = new MemoryStream(byte[] xxx);
BinaryFormatter bf = new BinaryFormatter();
反序列化类名 xxx = bf.Deserialize(stream) as 反序列化类名;

# 变量相关

# 可变参数

void function( params object[] args){}

# @开头的变量名

在 C#  规范中, @  可以作为标识符(类名、变量名、方法名等)的第一个字符,以允许 C# 中保留关键字作为自己定义的标识符。如

class @class
{
   public static void @static(bool @bool) {
      if (@bool)
         System.Console.WriteLine("true");
      else
         System.Console.WriteLine("false");
   }   
}

这样,对于跨语言的移植带来了便利。因为,某个单词在 C#  中作为保留关键字,但是在其他语言中也许不是。

# C# 中的指针使用

C# 为了类型安全,默认并不支持指针。但是也并不是说 C# 不支持指针,我们可以使用 unsafe 关键词,开启不安全代码 (unsafe code) 开发模式。在不安全模式下,我们可以直接操作内存,这样就可以使用指针了。在不安全模式下,CLR 并不检测 unsafe 代码的安全,而是直接执行代码。unsafe 代码的安全需要开发人员自行检测。(原文链接)

unsafe static void Main(string[] args){
    // 代码
}
unsafe
{
// 代码块
}

# 指针类型

C# 可以定义为指针的类型有 sbyte, byte, short, ushort, int, uint, long, ulong, char, float, double, decimal, bool,struct,结构体中只能包括非托管类型

# 指针操作符

操作符说明
*取值运算符
&取址运算符
->通过指针处理结构体中的数据(获取或赋值)
++ 与 --指针增、减操作
fixed用户暂时固定托管代码中引用类型的位置。
Stackallc分配内存

# fixed 应用

C# 在 GC 时在回收内存的同时会进行内存压缩,会导致堆中的地址重定向,如果使用了 fixed 关键字,那么就可以使当前内存地址跳过重定向,可用于操作类内的非托管类型

class A{
   public int b;
}
var a = new A();
a.b=0;
fixed(int* aPtr=&a.b)
{
    *aPtr += 1;
}
//a.b = 1

# Stackallc 的应用

主动申请内存分配

char* cptr = stackalloc char[26];
for (int i = 0; i < 26;i++ )
{
    cptr[i] = (char) (i+65);
}
for (int i = 0; i < 26;i++ )
{
    Console.WriteLine(string.Format("{0}:{1}",(int)&cptr[i],cptr[i]));
}

c# 并没有提供释放内存的函数,分配的内存会在方法结束后自动释放

# 指针定义

定义指针说明
int* p一个整型的指针
int** p指向整型指针的指针
int*[] arr整形一维数组的指针

# 指针的使用

# 整型指针

int i=10;
int* iptr = &i;    // 将 i 的地址赋值给 iptr
Console.WriteLine((int)&iptr);  // 取 iptr 得地址
Console.WriteLine(*iptr);     // 取 iptr 指向的值

# 结构体指针

struct Location
{
    public int X;
    public int Y;
}
unsafe static void Main(string[] args)
{
    Location location;
    location.X = 10;
    location.Y = 5;
    Location* lptr = &location;
    Console.WriteLine(string.Format("location 地址{0},lptr地址{1},lptr值{2}",(int)&location,(int)lptr,*lptr));
    Console.WriteLine(string.Format("location.x的地址{0},location.x的值{1}",(int)&(lptr->X),lptr->X));
    Console.WriteLine(string.Format("location.y的地址{0},location.y的值{1}", (int)&(lptr->Y), lptr->Y));
 }

# 指针与参数

public static unsafe int* Add(int* x,int* y)
{
    int sum = *x + *y;
    return &sum;
}
int i = 2, j = 3;
Console.WriteLine(*Add(&i,&j));

# 类与指针

c# 中的指针只能作用于非托管类型,因此无法声明类的指针,当类内存在非托管类型需要去操作时,可以使用指针 (参考 fixed 关键字)

class People
{
    public int Age;   // 值类型,不可以是属性
    public void ShowAge()
    {
        Console.WriteLine(Age);
    }
}
People people = new People();
people.Age = 10;
fixed(int* agePtr=&people.Age)
{
    *agePtr += 1;
}
people.ShowAge(); 
//11

# 访问类的内存地址

GCHandle 提供从非托管内存访问托管对象的方法

using System.Runtime.InteropServices
object p = new People();
GCHandle h = GCHandle.Alloc(p, GCHandleType.Pinned);
IntPtr addr = h.AddrOfPinnedObject(); 
Console.WriteLine(addr.ToString());
h.Free();

# 序列化反序列化

# Xml

xml 序列化类

using System.Xml.Serialization;
[System.Serializable]
public class TestSerilize 
{
    [XmlAttribute("Id")]
    public int Id { get; set; }
    [XmlAttribute("Name")]
    public string Name { get; set; }
    [XmlArray("List")]
    public List<int> List { get; set; }
}

序列化

using System.Xml.Serialization;
    void XmlSerilize(TestSerilize test)
    {
        using (var fs = new FileStream(Application.dataPath + "/test.xml", 
FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            var sw = new StreamWriter(fs, System.Text.Encoding.UTF8);
            var xml = new XmlSerializer(test.GetType());
            xml.Serialize(sw, test);
            sw.Close();
        }
    }

反序列化

using System.Xml.Serialization;
  void XmlDeserialize() 
    {
        using (var fs = new FileStream(Application.dataPath + "/test.xml", FileMode.Open, 
FileAccess.Read, FileShare.Read))
        {
            var xml = new XmlSerializer(typeof(TestSerilize));
            var data = (TestSerilize)xml.Deserialize(fs);
            Debug.Log($"{data.Id}  {data.Name}  {data.List.Count}");
        }
    }

# Binary

序列化

using System.Runtime.Serialization.Formatters.Binary;
    void BinarySerilize(TestSerilize test) 
    {
        using (var fs = new FileStream(Application.dataPath + "/test.bytes", 
FileMode.Create, FileAccess.ReadWrite, FileShare.ReadWrite))
        {
            var bf = new BinaryFormatter();
            bf.Serialize(fs, test);
        }
    }

反序列化

using System.Runtime.Serialization.Formatters.Binary;
   void BinaryDeserilize() 
    {
        using (var fs = new FileStream(Application.dataPath + "/test.bytes", 
FileMode.Open, FileAccess.Read, FileShare.Read))
        {
            var bf = new BinaryFormatter();
            var data = (TestSerilize)bf.Deserialize(fs);
            Debug.Log($"{data.Id}  {data.Name}  {data.List.Count}");
        }
    }
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

汘帆 微信

微信

汘帆 支付宝

支付宝