【C#语言入门】15. 方法参数进阶,扩展方法

【C#语言入门】15. 方法参数进阶,扩展方法

一、值参数

  • 声明时不带修饰符的形参是值形参。一个值形参对应于一个局部变量,只是它的初始值来自该方法调用所提供的相应实参。
  • 值参数创建变量的副本
  • 对值参数的操作永远不影响变量的值
class Program
{
    static void Main(string[] args)
    {
        Student stu = new Student();
        int y = 100;
        stu.AddOne(y);//101
        Console.WriteLine(y);//100
    }

}

class Student
{
    public void AddOne(int x)
    {
        x = x + 1; 
        Console.WriteLine(x);
    }
}
  • 引用类型,并且新创建对象
class Program
{
    static void Main(string[] args)
    {
        Student stu = new Student(){Name = "Tim"};
        SomeMethod(stu);//Tom
        Console.WriteLine;//Tim
    }
    
    static void SomeMethod(Student stu)
    {
        stu = new Student(){Name = "Tom"};
        Console.WriteLine(stu.Name);
    }
}

class Student
{
    public string Name {get; set;}
}
  • 引用类型,只操作对象,不创建新对象
  • 对象还是那个对象,但是对象里的值(字段/属性)已经改变

二、引用参数

  • 引用形参是用ref修饰符声明的形参。与值形参不同,引用形参并不创建新的存储位置。相反,引用形参表示的存储位置恰是在方法调用中作为实参给出的那个变量所表示的存储位置。变量在可以作为引用形参传递之前,必须先明确赋值。
  • 引用参数并不创建变量的副本。
  • 使用ref修饰符显式指出——此方法的副作用是改变实际参数的值。
static void Main(string[] args)
{
    int y = 1;
    IWantSideEffet(ref y);
    Console.WritreLine(y);
}

static void IWantSideEffect(ref int x)
{
    x = x + 100;
}
class Program
{
    static void Main(string[] args)
    {
        Student outterStu = new Student(){Name = "Tim"};
        Console.WriteLine("HashCode=(0),Name=(1)",outterStu.GetHashCode(),outterStu.Name);//Tim
        IWantSideEffect(ref outterStu);//Tom
        Console.WriteLine("HashCode=(0),Name=(1)",outterStu.GetHashCode(),outterStu.Name);//Tom
    }
    
    static void IWantSideEffect(ref Student stu)
    {
        stu = new Student(){Name = "Tom"};
        Console.WriteLine("HashCode=(0),Name=(1)",stu.GetHashCode(),stu.Name));
    }
}

class Student
{
    public string Name {get; set;}
}

三、输出形参

  • 通过利用输出参数来得到除了返回值之外的输出。
  • 用out修饰符声明的形参是输出形参,输出形参不创建新的存储位置,变量在可以作为输出形参传递之前不一定需要明确赋值,但是在方法返回之前,该方法的输出形参必须明确赋值。
  • 输出参数并不创建变量的副本
  • 方法体内必须要有对输出变量的赋值操作
  • 使用out修饰符显式指出——此方法的副作用是通过参数向外输出值
  • 从语义上来讲——ref是为了“改变”,而out是为了“输出”。
static void Main (string[] args)
{
    Console.WriteLine("Please input first number:");
    string arg1 = Console.ReadLine();
    double x = 0;
    bool b1 = double.TryParse(arg1, out x);
    if (b1 == false)
    {
        Console.WriteLine("Input,error.");
        return;
    }
    
    Console.WriteLine("Please input second number:");
    string arg2 = Console.ReadLine();
    double y = 0;
    bool b2 = double.TryParse(arg2, out y);
    if (b2 = false)
    {
        Console.WriteLine("Input,error.");
        return;
    }
    
    double z = x + y;
    Console.WriteLine("(0)+(1)=(2)", x, y, z);
}
class Program
{
    static void Main(string[] args)
    {
        Student sut = null;
        bool b =StudentFactory.Create("Tim", 34, out stu);
        if (b == true)
        {
            Console.WriteLine("Student (0),age is (1)", stu.Name, stu.Age);
        }
    }
}

class Student
{
    public int Age{get; set;}
    public string Name{get; set;}
}

class StudentFactory
{
    public static bool Create(string stuName, int stuAge, out Student result)
    {
        result = null;
        if(string.IsNullOrEmpty(stuName))
        {
            return false;
        }
        
        if(stuAge < 20 || stuAge > 80)
        {
            return false;
        }
        
        result = new Student(){Name = stuName,Age = stuAge};
        return true;
    }
}

四、数组参数

  • 数组参数只能有一个且必须是形参列表中的最后一个,用params修饰
static void Main(string[] args)
{
    int result = CalculateSum(1, 2, 3);
    Console.WriteLine(result);
}

static int CalculateSum(params int[] intArray)
{
    int sum = 0;
    foreach(var item in intArray)
    {
        sum += item;
    }
    return sum;
}

五、具名参数

  • 参数的位置不再受约束,提高可读性
static voi Main(string[] args)
{
    PringInfo(age:34, name:"Tim");
}

static void PrintInfo(string name, int age)
{
    Console.WriteLine("Hello(0), you are (1).", name, age);
}

六、可选参数

  • 参数因为具有默认值而变得“可选”
  • 不推荐使用可选参数

七、扩展方法(this参数)

  • 方法必须是公有的、静态的,即被public static所修饰
  • 必须是形参列表中的第一个,由this修饰
  • 必须由一个静态类(一般类名为SomeTypeExtension)来统一收纳对SomeType类型的扩展方法
class Program
{
    static void Main(string[] args)
    {
        double x = 3.1415926;
        double y = x.Round(4);  
        //double y = Math.Round(x,4);
        Console.WriteLine(y);
    }
}

static class DoubleExtension
{
    public static double Round(this double input, int digits)
    {
        double result = Math.Round(input,digits);
        return result;
    }
}

八、各种参数的使用场景总结

  • 传值参数:参数的默认传递方式
  • 输出参数:用于除返回值外还需要输出的场景
  • 引用参数:用于需要修改实际参数的场景
  • 数组参数:用于简化方法的调用
  • 具名参数:提高可读性
  • 可选参数:参数拥有默认值
  • 扩展方法:为目标数据类型“追加”方法
  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值