首页 > 编程语言 >C#的ref和out

C#的ref和out

时间:2024-09-08 21:16:10浏览次数:8  
标签:p1 Point C# ToString ref public out

CLR默认所有函数参数默认传值,在C#中无论是值类型还是引用类型的参数都是如此。对于值类型是传递了一个副本。

sealed class Program
{
    static void Main(string[] args)
    {
        
        Point p = new Point();
        Console.WriteLine(p.ToString());

        AddPoint(p);
        Console.WriteLine(p.ToString());
    }

    public static void AddPoint(Point p)
    {
        p.x += 1;
        p.y += 1;
    }
    public struct Point
    {
        public int x, y;
        public override string ToString() => $"({x}, {y})";
    }
}

上面的代码会输出两个(0,0),因为修改的是传入的副本的值而没有修改对象p本身。

对于引用类型是传递了一个对象的引用,这意味着我们无法改变作为参数传入的那个变量指向的对象。

sealed class Program
{
    static void Main(string[] args)
    {
        
        Point p = new Point();
        Console.WriteLine(p.ToString());

        AddPoint(p);
        Console.WriteLine(p.ToString());
    }
    public static void AddPoint(Point p1)
    {
        p1 = new Point();
        p1.x = 1;
        p1.y = 1;
    }
    public class Point
    {
        public int x, y;
        public override string ToString() => $"({x}, {y})";
    }
}

上面的代码会输出两个(0,0),因为只是修改p1指向的对象,而p指向的对象没有改变。

而通过使用refout关键字,我们可以改变上述默认行为,实现参数的引用传递。CLR中是不区分out和ref,无论使用哪个关键字都会生成相同的IL代码。但是C#编译器在处理refout时会进行一些额外的检查,以确保参数在使用前被正确赋值。

sealed class Program
{
    static void Main(string[] args)
    {
        Point p = new Point();
        Console.WriteLine(p.ToString());

        AddPoint(ref p);
        Console.WriteLine(p.ToString());
    }
    public static void AddPoint(ref Point p1)
    {
        p1 = new Point();
        p1.x = 1;
        p1.y = 1;
    }
    public class Point
    {
        public int x, y;
        public override string ToString() => $"({x}, {y})";
    }
}

上图代码会输出(0,0),(1,1),就是因为ref关键字使得传入了p的引用,因此AddPoint中修改了p1指向的对象也就修改了p指向的对象。

ref和out都能传引用,但是它们有如下的不同:

  • ref需要传入一个已经初始化过的对象。
  • out需要对象在函数内部有被写入过。

标签:p1,Point,C#,ToString,ref,public,out
From: https://www.cnblogs.com/wenxuanh/p/18403488

相关文章

  • AtCoder Beginner Contest 244 D~F 题解
    D-SwapHats题目大意有\(3\)个Takahashi,他们帽子的颜色分别为\(S_1,S_2,S_3\)。我们现在想通过正好\(10^{18}\)次操作,使得\(S_i=T_i\)。每次操作如下:选择\((i,j)\),交换\(S_i\)和\(S_j\)。试问能否达成目标?输入格式\(S_1~S_2~S_3\)\(T_1~T_2~T_3\)输出格式如果能达......
  • ARC138 B - 01 Generation 题解
    ARC138B-01Generation思路考虑逆向思维,很容易想到可以优先从后面删掉0(操作B的逆向操作),然后如果前面是0则删掉它并将序列翻转(操作A的逆向操作),一直重复这两个步骤直到字符串为空。如果中途无法操作,输出No,否则输出Yes。下面我们来证明这个方法的正确性:首先,假设有一个序列\(A......
  • C++宏
    宏是编译时预处理阶段用到的一种强大的工具,宏可以实现对指定代码片段的替换。依照笔者的理解,宏实际上是给某个特定的代码段起了一个别名。在预处理阶段,编译器将代码中的这个别名替换成相应的代码段。在C++当中,我们可以使用#define指令来定义宏。#definePI3.14159265358979......
  • AtCoder题解集锦
    注:本文原发表于CSDN,现已停止更新。原文如下:AtCoder题解集锦自己从全网整理的一些优质AtCoder题解,目前只有ABC(AtCoderBeginnerContest)的C~F。不定期更新。如您有更多需求,欢迎私信我或在评论区留言!\(\rarr\)题解列表传送门用法表格查找找到对应比赛的行找到对应......
  • AtCoder Beginner Contest 250 C~E 题解
    C-AdjacentSwaps题目大意\(N\)个球从左到右排成一列。开始时,从左往右的第\(i\)个球上写着数字\(i\)。请执行\(Q\)个操作,第\(i\)个操作如下:令\(j=~N\)个球中写着数字\(x_i\)的球的位置如果\(j=N\),将其与第\(j-1\)个球交换;否则,与第\(j+1\)个球交换。求所有操作后的球上分......
  • UNIQUE VISION Programming Contest 2022(AtCoder Beginner Contest 248)C~D 题解
    C-DiceSum题目大意有多少个整数序列\(A=(A_1,\dots,A_N)\)符合如下条件:\(1\leA_i\leM\)\(\sum\limits_{i=1}^NA_i\leK\)输出答案,对\(998244353\)取模。\(1\leN,M\le50\)\(N\leK\leNM\)输入格式\(N~M~K\)输出格式输出答案,对\(998244353\)取模。分析艹C题......
  • AtCoder Beginner Contest 252 A~G 题解
    前言这是我第一次写7题(A~G)的ABC题解,若有写得不好或者不到位的地方请多多指教,我将万分感激,感谢大家的支持!A-ASCIIcode题目大意给定正整数\(N\),输出ASCII码是\(N\)的字母。\(97\leN\le122\)输入格式\(N\)输出格式输出ASCII码是\(N\)的字母。分析注意a对应\(97\)......
  • AtCoder Beginner Contest 192 A~D 题解
    A-Star题目大意下一个大于\(X\)的\(100\)的倍数与\(X\)的差是多少?\(1\leX\le10^5\)输入格式\(X\)输出格式输出答案。样例\(X\)输出\(140\)\(60\)\(1000\)\(100\)分析下一个大于\(X\)的\(100\)的倍数是\((\lfloorX/100\rfloor+1)\times100\)。所......
  • AtCoder Beginner Contest 191 A~D 题解
    A-VanishingPitch题目大意一个球的速度是\(V~\text{m/s}\),它飞了\(T\)秒后会隐形,飞了\(S\)秒时会接触隐形。球在飞了\(D\)米后,人能看见它吗?输出Yes或者No。\(1\leV\le1000\)\(1\leT<S\le1000\)\(1\leD\le1000\)输入格式\(V~T~S~D\)输出格式输出答案。样例......
  • AtCoder Beginner Contest 190 A~D 题解
    A-VeryVeryPrimitiveGame题目大意Takahashi和Aoki在玩一个游戏。游戏规则是这样的:最开始,Takahashi和Aoki分别有\(A\)和\(B\)颗糖。他们将轮流吃一颗糖,第一个无法吃糖的人算输。如果\(C=0\),那么Takahashi先吃;如果\(C=1\),那么Aoki先吃。请输出最终胜者的名字。\(0\le......