我有这个数据类:
class MyClass
{
Foo Foo1 { get; set; }
Foo Foo2 { get; set; }
Foo Foo3 { get; set; }
Foo Foo4 { get; set; }
}
现在,在程序的其他位置,我具有以下功能:
void ModifyMyClass(MyClass myClassInstance)
{
var rightFooToModify = myclassInstance.Foo1;
rightFooToModify = new Foo(); // Here, my intention is to
// modify MyClass, not just the
// local variable 'rightFooToModify'
}
我需要能够选择Foo1,Foo2,Foo3,Foo4(取决于某些条件)之一,然后将其设置为新的Foo对象。
实现此目标的最佳方法是什么?我可以在C#中使用某种参考变量吗?
编辑:
我可以使用(实际上是我现在使用的):
myClassInstance.Foo1 = new Foo();
但是,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.
}
}
我想避免在接下来的所有if
中的else if
块中重复代码。这就是为什么我只想在方法开始时使用var rightFooToModify = myClassInstance.Foo1
,而不是在多个if
s中不必要地复制代码。
答案 0 :(得分:0)
您可以这样想
将属性分配给局部变量时,
var rightFooToModify = myclassInstance.Foo1;
您要做的就是写一个便签纸,上面留有一些内存。
如果有人给您另一个便条纸,则替换原始便条纸
rightFooToModify = new Foo();
它不会改变原始内存,它仍然存在,什么也没发生。
这是指针/引用的工作方式。它们指向/引用内存中的位置,您可以复制引用但覆盖该引用对原始内存位置没有任何作用,只是有一个指向其他地方的新便笺。
但是,现在举一个用ref return
和ref Local
克服这一问题的方法的真正人为例子
免责声明 ,我并不主张在您遇到的情况下这样做,但是出于纯粹的学术目的,让我们看一下这种语言 功能
给予
public class MyClass
{
private Foo _foo1;
public Foo Foo1
{
get => _foo1;
set => _foo1 = value;
}
public ref Foo ModifyMyClass()
{
return ref _foo1;
}
}
示例
// 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);
输出
test
test3
还有另一个奇怪而怪异的引用用法
someClass.ModifyMyClass() = new Foo();
someClass.ModifyMyClass().SomeValue = "I hope i never see this in my code base";
Console.WriteLine(someClass.Foo1.SomeValue);
答案 1 :(得分:0)
我不知道这是否有帮助,但是您可以使用一种方法来返回类型为boolean win() {
return (fc == 3 && fm == 3) ? false : true;
/// or better: return !(fc == 3 && fm == 3);
}
的正确的setter,即
Action<MyClass, Foo>
然后这样称呼它:
Action<MyClass, Foo> GetFooSetter()
{
if (someCondition)
{
return (myClass, foo) => myClass.Foo1 = foo;
}
else if (someOtherCondition)
{
return (myClass, foo) => myClass.Foo2 = foo;
}
}
答案 2 :(得分:0)
用例不太清楚,所以我建议两个选择:
如果Foo
不是不可变的,则只需修改其值,而不是将其分配给新实例。您甚至可以添加复制功能来从另一个Foo
复制值:
Foo fooToChange = myClassInstance.Foo1;
fooToChange.CopyFrom(new Foo());
重构以将Foos保留在数组中,然后您可以要求它并分配一个索引:
class MyClass
{
public Foo[] Foos = new Foo[4];
}
int fooToChange = 3;
myClassInstance.Foos[3] = new Foo();