`
pcajax
  • 浏览: 2162675 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

关于C#函数对象参数传递的问题

阅读更多


   我们知道在.net里class是引用类型,在函数参数表中的对象传递的都是对象的引用,所以在函数体内对其对象参数的修改会影响函数外对应的对象本身,例如下面的程序:

    class Program
    {
        static void Main(string[] args)
        {
            TestClass objA = new TestClass();
            objA.Name = "I am ObjA";

            Console.WriteLine(String.Format("In Main:{0}", objA.Name));

            TestFun(objA);

            Console.WriteLine(String.Format("In Main:{0}", objA.Name));

            Console.Read();
        }

        static void TestFun(TestClass obj)
        {
            obj.Name = "I am be modified in TestFun";
            Console.WriteLine(String.Format("In TestFun:{0}", obj.Name));
        }

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

  将对象objA作为参数传递给函数TestFun,这时传递的是对象objA的引用,所以在函数内对objA的修改会直接应用到这个对象本身。在函数TestFun内修改了形参obj的Name属性,所以在Main中再调用objA.Name时这个属性值就变为在TestFun中修改后的值了。这一点很好理解,运行结果也就是:

image

    如果我们换一种写法:

    class Program
    {
        static void Main(string[] args)
        {
            TestClass objA = new TestClass();
            objA.Name = "I am ObjA";

            Console.WriteLine(String.Format("In Main:{0}", objA.Name));

            TestFun(objA);

            Console.WriteLine(String.Format("In Main:{0}", objA.Name));

            Console.Read();
        }

        static void TestFun(TestClass obj)
        {
            TestClass objB = new TestClass();
            obj = objB;
            obj.Name = "I am ObjB";
            Console.WriteLine(String.Format("In TestFun:{0}", obj.Name));
        }

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

    那结果又将如何呢? 在TestFun中新创建了一个对象objB,接着将obj指向新创建的对象objB并对其的Name属性赋值,所以在TestFun函数体里Console.WriteLine的时候obj.Name应该是“I am ObjB”。那在Main里调用了TestFun(objA)后objA指向的对象到底做了改变没有,它仍旧指向原来的对象还是已经指向了在TestFun里创建的objB呢?

    我的猜测是这样的,将objA传递给TestFun传递的实际是objA的地址,在调用TestFun之前的对应关系是:

image

   objA是个变量,他本身的地址是000001,它存放的是objA对象的地址00E001。当调用函数TestFun(objA)时,由于要将objA作为参数传递给TestFun,所以在
栈中就复制一个objA地址的副本,这个副本的地址为000003,他存放的仍旧是objA对象的地址00E001,如图:

image

   所以在TestFun函数中,一开始obj指向的还是objA对象。当在TestFun中创建了一个对象objB后,内存模型变为:

  image

  TestFun中执行“obj=objB”后,obj指向objB对象,如下图:

image

  所以执行完TestFun函数后,Main函数中objA仍旧指向原来的objA对象,故运行结果如下:

image

 

:本文中的内存模型仅是个人猜测,肯定有不正确或者不严谨的地方,希望不要误导大家,也欢迎指正。


分享到:
评论

相关推荐

    c# 调用C++编写 的DLL函数各种参数传递问题。

    C# 调用 C++ 编写的 DLL 函数各种参数传递问题 在 C# 调用 C++ 编写的 DLL 函数时,参数传递是一个非常重要的部分。这篇文章将详细介绍 C# 调用 C++ 编写的 DLL 函数各种参数传递问题,包括不返回值的参数、带...

    C#动态调用DLL并对目标函数传递参数

    6. **传递参数**:动态调用时,`DynamicInvoke`方法接收一个对象数组作为参数,数组中的元素顺序应与目标函数的参数顺序一致。如果目标函数有返回值,`DynamicInvoke`会返回该值。 注意,如果DLL函数使用了非托管...

    C#与MATLAB之间传递参数

    C#与MATLAB之间传递参数 C#和MATLAB是两个不同的编程语言,C#是微软公司开发的面向对象的高级编程语言,而MATLAB是MATLAB公司开发的高性能数值计算语言。两者之间的数据传递是非常重要的,因为在实际应用中,我们...

    C# 获取调用函数 参数名称和值

    在获取参数值时,你需要将实际的参数传递给`Invoke`,这在大多数情况下可能无法实现,因为我们通常没有调用函数的实际上下文。在不修改调用代码的情况下,获取参数值的常规方法在C#中并不直接支持,除非你使用AOP...

    C#多态性实例,向基类构造函数传递参数.rar

    3. **参数传递的意义**:向基类构造函数传递参数使得我们可以根据派生类实例化时的具体条件来设置基类的状态。这有助于保持代码的灵活性和可扩展性,因为基类的行为可以根据派生类的特性进行调整。 4. **封装和抽象...

    c# 参数传递,参数调用

    在C#编程语言中,参数传递和参数调用是核心概念,它们关乎着函数和方法如何接收和处理数据。理解这些概念对于编写高效且可维护的代码至关重要。本篇文章将深入探讨C#中的参数传递机制及其应用。 首先,我们要了解...

    C#控制台程序之间参数传递

    在C#编程中,控制台程序之间的参数传递是一项常见的任务,尤其在系统集成或脚本自动化等场景下。本文将详细讲解如何从一个控制台应用程序(源程序)启动另一个控制台应用程序(目标程序),并传递参数字符串,以及...

    C# 的函数编程详解

    【C#函数编程详解】 函数式编程是一种编程范式,它强调使用函数作为核心构建块,将计算视为函数的组合,而不是状态的变化或指令的序列。近年来,由于其简洁、可读性强和易于并行处理的特点,函数式编程在IT行业中...

    C#中的参数传递 .doc

    当引用类型作为参数传递时,实际上是传递了引用的副本,但由于引用类型的特性,这仍然允许在函数内修改原始对象。 3. **按输出传递(Pass by Output)**:使用`out`关键字,可以用于任何类型。这种传递方式要求在...

    C#_函数手册大全+c#公共函数

    本资源包含了"C#_函数手册大全+c#公共函数",旨在为开发者提供全面的C#函数参考资料。下面我们将详细探讨这两个文档可能涵盖的关键知识点。 一、C#函数基础 1. 函数定义:C#中的函数通过`void FunctionName(params)...

    C#调用C++编写的DLL函数各种参数传递

    ### 一、字符串参数传递 C#调用C++ DLL函数时,最常见的一种情况是处理字符串参数。例如,考虑以下C++函数: ```cpp bool SendNewSms(char* szTel, char* szMessage); ``` 对应的C#调用如下: ```csharp ...

    C# 调用带参数EXE文件及带启动参数EXE制作

    在C#编程中,有时我们需要创建可执行文件(EXE)并传递参数,或者从一个应用程序调用另一个带有参数的EXE。以下是如何在C#中实现这些功能的详细步骤。 首先,我们来讨论如何创建一个带启动参数的EXE文件: 1. 定义...

    c#函数使用说明

    函数使用说明通常包括函数的定义、参数、返回值、使用示例以及可能遇到的问题和解决方案。以下是对C#函数的一些详细说明: 1. **函数定义**: 在C#中,函数定义以`public`、`private`等访问修饰符开始,接着是返回...

    C#函数手冊级代码解析

    "C#函数手册级代码解析"是一个深入理解C#函数和代码实现的重要资源,它旨在帮助开发者更高效地理解和运用C#语言中的函数和代码结构。 C#中的函数是可重用的代码块,它们执行特定的任务,并可能接收参数以定制其行为...

    C#中的参数传递 - ref, out比较

    在C#语言中,函数或方法的参数传递方式是一个重要的概念。本文将深入解析C#中涉及的几种关键参数传递机制:值类型的基本传递、`ref`关键字以及`out`关键字,并通过具体示例来说明这些传递方式的区别及应用场景。 ##...

    asp.net(C#)函数对象参数传递的问题

    总的来说,C#中的对象参数传递特性对于理解和调试代码非常重要。理解这种行为可以帮助我们避免意外地修改了原本不想修改的对象,同时也能有效地利用引用传递来共享和修改数据。在编写函数时,要清楚地知道参数是值...

    C#传递回调函数

    在C#编程中,回调函数是一种非常重要的设计模式,它允许我们将一个方法的引用作为参数传递给另一个方法,这样在特定条件下,被传递的方法可以被调用执行。在这个场景中,我们讨论的是如何在C#中传递回调函数给ATL...

    c#参数传递c#参数传递

    在C#编程语言中,参数传递是一个至关重要的概念,它涉及到函数调用时,实参(函数调用时提供的值)如何与形参(函数定义中的变量)交互。C#支持两种基本的参数传递方式:值传递和引用传递。下面我们将深入探讨这两种...

    C# 实现回调函数

    回调函数通常用于异步编程,事件处理或者作为参数传递,使得代码更加灵活和可扩展。接下来,我们将深入探讨C#中实现回调函数的原理、方式以及应用场景。 首先,我们需要理解什么是回调函数。回调函数本质上就是一个...

    C#多态性实例,向基类构造函数传递参数

    // 子类构造函数,调用基类构造函数并传递参数 public DerivedClass(string commonValue, string derivedValue) : base(commonValue) // 调用基类构造函数 { DerivedProperty = derivedValue; } } ``` 在这个...

Global site tag (gtag.js) - Google Analytics