clr via c# 参数和属性

1,可选参数和命名参数

  • 当给参数指定默认值时,可以在调用的时候省略
  • 有默认值的参数,必须放在所有没有默认值的参数后面,但是 参数数组必须放在最后面,parm
  • 默认值必须时编译时能确定的常量值,对于值类型可以用default(类型)关键字来给定。
  • 如果参数用ref或者out设定,则没法使用默认值
  • 对于有ref的参数调用,以传参数名的方式传递实参,则使用如下语法:
private static void M(ref int x){...}

int a=5;
//调用方法
M(x:ref a);
class Program
    {
        private static int s_n = 0;
        private static void M(int x=9,string s ="A",DateTime dt=default(DateTime),Guid guid=new Guid())
        {
            Console.WriteLine("x={0},s={1},dt={2},guid={3}", x, s, dt, guid);
        }
        static void Main(string[] args)
        {
            M();
            M(8, "X");
            M(5, guid: Guid.NewGuid(), dt: DateTime.Now);
            M(s_n++, s_n++.ToString());
            M(s: s_n++.ToString(), x: s_n++);
            Console.ReadKey();
        }
    }


//-----------------------------结果
x=9,s=A,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
x=8,s=X,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
x=5,s=A,dt=2020/1/30 9:47:08,guid=89e5fcd4-2a7f-4872-968e-756a4dfa9531
x=0,s=1,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000
x=3,s=2,dt=0001/1/1 0:00:00,guid=00000000-0000-0000-0000-000000000000

2,DefaultParameterValueAttribute 和 OptionAttribute----------IL代码读懂IL指令大全

3,参数传递方式

  • 传值(默认),注意,传递引用本身时传值的。相当于传递了一个指针的副本。
  • 传引用,使用ref,out关键字,则传递的实际时参数的地址,而不是一个副本。
  • ref和out方法的区别:
  •  private static void GetVal(out int v)
            {
                v = 10;
            }
            private static void callGetVal()
            {
                int x;//可以不必初始化
                GetVal(out x);//但是在函数内部必须初始化。
                Console.WriteLine(x);
            }
     private static void GetVal(ref int v)
            {
                v += 10;
            }
            private static void callGetVal()
            {
                int x=5;//必须初始化。否则报错errorCS0165使用未赋值局部变量x;
                GetVal(ref x);//在函数内部不必初始化。
                Console.WriteLine(x);
            }
    
    •     对于ref或者out关键字最大的区别在于初始化的位置,ref必须在方法的外部,out 则必须在方法内部初始化。
    • 考虑 以下代码,就知道区别了。
    • public class RefUsedType
              {
                  public string value { get; set; }
                  public RefUsedType(string value)
                  {
                      this.value = value;
                  }
                  public static void  deal(ref RefUsedType r1)
                  {
                      r1 = new RefUsedType("r2");
                  }
                  public static void deal( RefUsedType r1)
                  {
                      r1 = new RefUsedType("r2");
                  }
              }
              public static void callRef()
              {
                  var r1 = new RefUsedType("r1");
                  RefUsedType.deal(r1);
                  Console.WriteLine(r1.value);
                  RefUsedType.deal(ref r1);
                  Console.WriteLine(r1.value);
      
              }
      //运行结果:
      r1//表明传值的方式---方法(被调用者,callee)不会改变调用者(callee)的实参的值---对于引用对象,则表现为其指向的对象
      永远不变(但是被调用者可以改变对象的内容,比如对象的属性,对象的字段等)
      r2//表面传引用的方式---方法会改变调用者的实参的值。相当于C++中的引用(@),对于引用对象,可以令其指向新对象或者为Null;

                 操作符重载的版本

public class RefUsedType
        {
            public string value { get; set; }
            public RefUsedType(string value)
            {
                this.value = value;
            }
            public static void  deal(ref RefUsedType r1)
            {
                r1 = "r2";
            }
            public static void deal( RefUsedType r1)
            {
                r1 = "r2";
            }
            public static implicit operator RefUsedType(string value)
            {
                return new RefUsedType(value);
            }
        }
        public static void callRef()
        {
            RefUsedType r1 = "r1";
            RefUsedType.deal(r1);
            Console.WriteLine(r1.value);
            RefUsedType.deal(ref r1);
            Console.WriteLine(r1.value);

        }

4,对象和集合初始化器

Employee e = new Employee(){Name="abc",Age=5}

可以简化为

Employee e = new Employee{Name="abc",Age=5}
List<string> ls = new List<string>{"s1","s2","s3"}的方式进行创建。
//并且,其支持上下文操作:
//比如
List<string> ls = new List<string>{"s1","s2","s3"}.ForEach(x=>x.console.writeline(x));

用于初始化类实列。

当类是一个集合类的时候,还支持类似上面的用法

匿名类型

var o1 = new {Name ="absd",year="dss"};

5,有参属性

public class BitArray
        {
            private byte[] m_byteArray;
            private int m_numBits;
            public BitArray(int numBits)
            {
                if (numBits <= 0)
                    throw new ArgumentOutOfRangeException("numBits must be >0");
                m_numBits = numBits;
                m_byteArray = new byte[(numBits + 7) / 8];//如何建立容纳N个位的字
            }
            public bool this[int bitPos]//索引器
            {
                get
                {
                    if ((bitPos < 0) || (bitPos > m_numBits))
                        throw new ArgumentOutOfRangeException("bitpos");
                    return (((m_byteArray[bitPos / 8]) & (1 << (bitPos % 8))))!=0;//如何查看第N位的状态。
                }
                set
                {
                    if ((bitPos < 0) || (bitPos > m_numBits))
                        throw new ArgumentOutOfRangeException("bitpos");
                    if (value)
                    {
                        m_byteArray[bitPos / 8] = (byte)
                            ((m_byteArray[bitPos / 8]) | (1 << (bitPos % 8)));//如何设ON第N位
                    }
                    else
                    {
                        m_byteArray[bitPos / 8] = (byte)
                            ((m_byteArray[bitPos / 8]) & ~(1 << (bitPos % 8)));如何设OFF第N位
                    }
                }
            }
        }
        public static void call_bitArray()
        {
            var b1 = new BitArray(18);
            b1[13] = true;
            for (var i = 0; i < 18; i++)
            {
                if (b1[i])
                    Console.WriteLine("on");
                else
                    Console.WriteLine("off");
            }
        }
//结果

off----第0位
off
off
off
off
off
off
off
off
off
off
off
off
on----第13位
off
off
off
off

clr via c# 参数和属性

上一篇:学习koa开发API(四)--- 文件目录设置


下一篇:01-flink时间语义 与 Window 基础概念与实现原理