[英]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 return
和ref 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: 用例不是很清楚,所以我建议两个选择:
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());
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.