c# in out ref关键字

class in_out_ref
    {
        #region in 关键字

        delegate void DContravariant<in A>(A argumen);

        static void objFunction(object obj)
        {
            Console.WriteLine("你变了");
        }
        static void strFunction(string str)
        {
            Console.WriteLine(str);
        }

        #endregion

        static void Main(string[] args)
        {
            #region in关键字

            // in关键字可指定类型参数是逆变的。
            // 逆变使你使用的类型可以比泛型参数指定的类型派生程度更小。

            DContravariant<object> f1 = objFunction;
            //DContravariant<string> f1 = objFunction;  // 可以使用string类型参数传入in object
            DContravariant<string> f2 = strFunction;
            f2 = f1; // string类型可以向object转换。
            f2("执行了");

            #endregion

            #region out、ref关键字
            
            // out、ref关键字允许调用方法修改实参的值
            // out修饰的参数必须在function内被修改
            // ref修饰的参数必须在调用function前赋值

            string str1;
            outFunction(out str1);
            Console.WriteLine(str1);

            string str2 = string.Empty;
            refFunction(ref str2);
            Console.WriteLine(str2);

            #endregion
        }

        static void outFunction(out string str)
        {
            str = "我被out了";
        }
        static void refFunction(ref string str)
        {
            str = "我被ref了";
        }
    }