C#ref和out的冷知识,ref修饰函数返回值,out泛型协变修饰符

本文通过C#实例展示了常规ref和out参数的使用,介绍了如何通过ref实现返回值引用,并剖析了协变和逆变泛型的概念,通过实际代码演示了这两种高级特性在类和接口中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常规ref和out

常规ref

用于向函数传递引用变量
如:

public void Func(ref int num)
{
	。。。
}

常规out

用于多类型多个返回值的函数。
如:

public bool Func(in int num , out int count, out string msg)
{
	。。。
}

修饰返回值的ref

ref实现

定义存储柜类

        //储物柜
        public class Locker
        {
                private int[] _Nums = new int[10];
                private int index = 0;
                public ref int Save(int num)
                {
                        if (index >= 10)
                        {
                                index = 0;
                        }
                        _Nums[index] = num;

                        return ref _Nums[index++];
                }

                public void Show()
                {
                        Console.WriteLine(string.Join(',', _Nums));
                }
        }

调用

private static void Main(string[] args)
{
	Locker locker = new Locker();
    {
		locker.Save(5);//存入 5 

		ref int r = ref locker.Save(6);//存入6 然后持有6这个数字的引用

		Console.WriteLine(r); //输出:6

		r = 666;//把6改为666
	}
	locker.Show(); //输出为:5,666,0,0,0,0,0,0,0,0
}

指针实现

定义储存柜类

        public class Locker1
        {
                private int[] _Nums = new int[10];
                private int index = 0;
                public unsafe int* Save(int num)
                {
                        if (index >= 10)
                        {
                                index = 0;
                        }
                        fixed (int* r = &(_Nums[index++]))
                        {
                                *r = num;

                                return r;
                        }
                }

                public void Show()
                {
                        Console.WriteLine(string.Join(',',_Nums));
                }
        }

调用

private static void Main(string[] args)
{
       Locker1 locker1 = new Locker1();
       
       unsafe
       {
               locker1.Save(5);//存入 5 

               int* r1 = locker1.Save(6);//存入6 然后持有6这个数字的指针
               
               Console.WriteLine(*r1);//输出:6

               *r1 = 666;//把6改为666

       }
       locker1.Show();//输出为:5,666,0,0,0,0,0,0,0,0
}

以最简单的方式看“协变泛型”和“逆变泛型”

        //interface InterfaceA<T>{ }//普通泛型接口A
        interface InterfaceA<out T>{ }//协变泛型接口A
        //interface InterfaceA<in T>{ }//逆变泛型接口A
        class A<R> : InterfaceA<R> { }//类A 实现接口A
        class B { }//类B
        class C:B { }//类C 继承类B
        internal class Program
        {
                private static void Main(string[] args)
                {
                        InterfaceA<B> b = new A<B>();
                        InterfaceA<C> c = new A<C>();
                        //没有特别修饰的情况下 不论 b = c 还是 c = b 都无法通过
                        b = c;//协变支持:子类对象 -> 父类对象
                        //c = b;//逆变支持:父类对象 -> 子类对象
                }
        }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值