我出于好奇而问这个问题,我知道其他方法。
我想知道,如果某个方法返回某种类型的对象,我们可以直接修改该对象的属性(动态 - 不将其引用到局部变量中)。
为什么我们需要将它的引用带入局部变量来改变对象本身?
在编译器级别存在哪些逻辑上的困难会限制程序员这样做。
请参阅下面的示例代码:
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);
答案 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改变