简体   繁体   English

实例成员的引用变量

[英]Reference variable to an instance member

I have this data class: 我有这个数据类:

class MyClass
{
    Foo Foo1 { get; set; }
    Foo Foo2 { get; set; }
    Foo Foo3 { get; set; }
    Foo Foo4 { get; set; }
}

Now, somewhere else in my program, I have this function: 现在,在程序的其他位置,我具有以下功能:

void ModifyMyClass(MyClass myClassInstance)
{
    var rightFooToModify = myclassInstance.Foo1;

    rightFooToModify = new Foo();  // Here, my intention is to
                                   // modify MyClass, not just the
                                   // local variable 'rightFooToModify'
}

I need to be able to choose one of Foo1, Foo2, Foo3, Foo4 (depending on some conditions) and then set it to a new Foo object. 我需要能够选择Foo1,Foo2,Foo3,Foo4(取决于某些条件)之一,然后将其设置为新的Foo对象。

What would be the best way to achieve this? 实现这一目标的最佳方法是什么? Are there some kind of reference variable that I can use for this in C#? 我可以在C#中使用某种参考变量吗?

EDIT: 编辑:

I could use (and it is actually what I use right now): 我可以使用(实际上是我现在使用的):

myClassInstance.Foo1 = new Foo();

But, ModifyMyClass() is actually a bit more complicated, for example: 但是,ModifyMyClass()实际上要复杂一些,例如:

void ModifyMyClass(MyClass myClassInstance)
{
    if (someCondition)
    {
        var rightFooToModify = myClassInstance.Foo1
        // ... Do some computation with rightFooToModify
        myClassInstance.Foo1 = new Foo(/* some parameters */);
    }
    else if (someOtherCondition)
    {
        // The exact same code as the if above , but with
        // myClassInstance.Foo2 instance.
    }
}

I would like to avoid duplicating the code in the if block in all the following else if . 我想避免在以下所有else if复制if块中的代码。 That is why I would like to just use var rightFooToModify = myClassInstance.Foo1 at the start of the method and not duplicate the code needlessly in mutliple if s. 这就是为什么我想只要使用var rightFooToModify = myClassInstance.Foo1在方法的开始,而不是无谓地重复码复式if秒。

You can think of it like this 你可以这样想

When you assign your property to a local variable, 当您将属性分配给局部变量时,

var rightFooToModify = myclassInstance.Foo1;

all you are doing is writing a post-it-Note with the location of some memory on. 您要做的就是写一个便笺纸,上面留有一些内存。

If someone gives you another post-it-note with some more, replacing the original one 如果有人给您另一个便条纸,并替换其他便条纸

rightFooToModify = new Foo();

It doesn't change the original memory, its still there, nothing happened. 它不会改变原始内存,它仍然存在,什么也没发生。

This is how pointers/references work. 这就是指针/引用的工作方式。 They point/reference a location in memory, you can copy a reference yet overwriting that reference doesn't do anything to the original memory location, you just have a new post-it-note pointing to somewhere else. 它们指向/引用内存中的位置,您可以复制引用但覆盖该引用不执行任何操作到原始内存位置,只是有一个指向其他地方的新便笺。

However, now for a really contrived example of a way to overcome this with ref return and ref Local 但是,现在举一个使用ref returnref Local克服此问题的方法的真实设计示例

Disclaimer , i don't really advocate doing this in your situation, however for sheer academic purposes lets look at this language feature 免责声明 ,我不主张在您遇到的情况下这样做,但是出于纯粹的学术目的,请查看此语言功能

Given 特定

public class MyClass
{
   private Foo _foo1;

   public Foo Foo1
   {
      get => _foo1;
      set => _foo1 = value;
   }

   public ref Foo ModifyMyClass()
   {
      return ref _foo1;
   }
}

Example

// create class
var someClass = new MyClass();

// create some memory for it
someClass.Foo1 = new Foo();
someClass.Foo1.SomeValue = "test";

// copy the reference to it
var copy = someClass.Foo1; 

// overwrite it
copy = new Foo();
copy.SomeValue = "test2";

// oh nossssssssss!!!! is didn't change!!
Console.WriteLine(someClass.Foo1.SomeValue);


//enter ref local
ref var  actualLocation = ref someClass.ModifyMyClass();

// create some memory
actualLocation = new Foo();
actualLocation.SomeValue = "test3";

// omg it worked!!!!
Console.WriteLine(someClass.Foo1.SomeValue);

Output 产量

test
test3

And yet another bizarre and weird usage of ref ref的另一种怪异而怪异的用法

someClass.ModifyMyClass() = new Foo();
someClass.ModifyMyClass().SomeValue = "I hope i never see this in my code base";
Console.WriteLine(someClass.Foo1.SomeValue);

I don't know if this will be of any help, but you can have a method returning the correct setter of type Action<MyClass, Foo> , ie 我不知道这是否会有帮助,但是您可以使用一种方法来返回类型为Action<MyClass, Foo>的正确设置器,即

Action<MyClass, Foo> GetFooSetter()
{
    if (someCondition)
    {
        return (myClass, foo) => myClass.Foo1 = foo;
    }
    else if (someOtherCondition)
    {
        return (myClass, foo) => myClass.Foo2 = foo;
    }
}

and then call it like this: 然后这样称呼它:

GetFooSetter()(myClassInstance, new Foo());

The use case is not so clear, so I will suggest two options: 用例不是很清楚,所以我建议两个选择:

  1. If Foo is not immutable, then just modify it's values instead of assigning it to a new instance. 如果Foo不是不可变的,则只需修改其值,而不是将其分配给新实例。 You can even add a copy function to copy values from another Foo : 您甚至可以添加复制功能来从另一个Foo复制值:

     Foo fooToChange = myClassInstance.Foo1; fooToChange.CopyFrom(new Foo()); 
  2. Refactor to hold the Foos in an array, then you can ask for it and assign with an index: 重构以将Foos保留在数组中,然后可以要求它并分配一个索引:

     class MyClass { public Foo[] Foos = new Foo[4]; } int fooToChange = 3; myClassInstance.Foos[3] = new Foo(); 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM