为什么我们不能直接将对象分配给返回相同类型的方法?

时间:2018-06-06 03:05:59

标签: c# object methods reference

我出于好奇而问这个问题,我知道其他方法。

我想知道,如果某个方法返回某种类型的对象,我们可以直接修改该对象的属性(动态 - 不将其引用到局部变量中)。

为什么我们需要将它的引用带入局部变量来改变对象本身?

在编译器级别存在哪些逻辑上的困难会限制程序员这样做。

请参阅下面的示例代码:

static Demo StaticDemoInstance;
static void Main(string[] args)
{
    //allowed: means I can directly modify property of static instance
    //  received from method
    GetDemo().Name = "UpdateDemo";

    //allowed: means I can get instance and overwrite it with other instance
    //      but not directly from method
    Demo d = GetDemo();
    d = new Demo("NewCreatedDemo", false);

    //not allowed: means I can't do second step directly on method
    //  question: 
    //      when I can update instance property without receiving instance on local variable
    //      what possible violation/difficulty (in compiler) will be there so it doesn't allow this
    GetDemo() = new Demo("UpdatedDemoFromGetMeth", false);
}

static Demo GetDemo() => StaticDemoInstance ?? 
                         StaticDemoInstance = new Demo("StaticDemo", false);

1 个答案:

答案 0 :(得分:6)

您始终可以使用Ref return

  

从C#7.0开始,C#支持引用返回值(ref   回报)。引用返回值允许方法返回a   将变量而不是值引用回调用者。该   然后,调用者可以选择将返回的变量视为处理   按值或按引用返回。调用者可以创建一个新的   变量本身是对返回值的引用,称为   ref local。

<强>限制

  

方法可以返回的表达式有一些限制   作为参考回报值。限制包括:

     
      
  • 返回值的生命周期必须超出方法的执行范围。换句话说,它不能是局部变量   在返回它的方法中。它可以是实例或静态字段   一个类,或者它可以是传递给该方法的参数。尝试   返回一个局部变量生成编译器错误CS8168,&#34;不能   返回本地&#39; obj&#39;通过引用,因为它不是本地的参考。&#34;

  •   
  • 返回值不能是文字null。返回null会生成编译器错误CS8156,&#34;表达式不能用于此   上下文,因为它可能不会被引用返回。&#34;

  •   
  • 带有ref返回的方法可以将别名返回到其值当前为null(未实例化)值或可空类型的变量   对于值类型。

  •   
  • 返回值不能是常量,枚举成员,属性的按值返回值,或类的方法或   结构。违反此规则会生成编译器错误CS8156,&#34; An   表达式不能在此上下文中使用,因为它可能不是   通过引用返回。&#34;

  •   

一个非常人为的例子而不是我的推荐,但它确实实现了你的目标(学术上)

示例

static Demo StaticDemoInstance;

...

static ref Demo GetDemo()
{
   if (StaticDemoInstance == null)
      StaticDemoInstance = new Demo("StaticDemo", false);

   return ref StaticDemoInstance;
}

..

GetDemo() = new Demo("UpdatedDemoFromGetMeth", false);

<强>更新

可以通过进一步复杂的例子和修改看到它的使用

Exmaple

static Demo Test()
{
   return StaticDemoInstance;
}

...

GetDemo() = new Demo("UpdatedDemoFromGetMeth", false);
var someObject = Test();
someObject= new Demo("Test", false);

Console.WriteLine(StaticDemoInstance.Name);
Console.WriteLine(someObject.Name);

<强>输出

UpdatedDemoFromGetMeth
Test

Test方法(不是引用返回)并且只提供引用的副本(缺少更好的术语),如果你覆盖它,你的静态变量StaticDemoInstance不会#39} ; t改变