我正在尝试执行以下操作:
-从第一种方法中,我要遍历一堆(相同类型的)对象,并将指向特定属性的指针提取到列表中
-此列表将在某个时间点馈入程序其他位置的另一种方法,并且必须修改原始对象的所有属性(按照提供的列表)
换句话说,我们有以下课程:
public class Something
{
public SomeFlag = False;
public Something()
{
}
}
在系统中的某个地方,我们将对象的相关列表组成了List。
现在,我们要浏览此列表,并将所有标志提取出来(通过引用?)到“ List
List<bool> flags = new List<bool>();
foreach (var stuff in List<Something>)
{
flags.Add(stuff.SomeFlag);
}
最后,我想在其他地方更新这些标志,但是更新应该会影响原始对象:
public static void SetStates(List<bool> myList)
{
// The flag should get set to true by reference in the original object
myList.SomeFlag = True;
}
答案 0 :(得分:1)
使用actions
是实现这一目标的一种方法:
public class Something
{
public bool SomeFlag { get; set; }
}
internal class Program
{
private static void Main()
{
var somethings = new[] {new Something(), new Something()};
var flags = new List<Action<bool>>();
// create your list of 'pointers'
foreach (var something in somethings)
{
flags.Add(x => something.SomeFlag = x);
}
// set them all to true
foreach (var action in flags)
{
action(true);
}
// check the results
foreach (var something in somethings)
{
Console.WriteLine(something.SomeFlag);
}
Console.WriteLine("press any key to exit...");
Console.ReadLine();
}
}
答案 1 :(得分:1)
在C#中,您无法保存对属性值的引用(如指向存储该值的内存位置的指针)。您只能保存对包含该属性值的对象的引用。
在var list = new List<Something>()
中,您可以存储对对象的引用。
请注意,虽然对于值类型来说这是不可能的。如果Something
是struct
,而不是class
,则list
将包含对象的副本,而不是对象的引用。因此,我的其余答案都假设我们正在谈论class Something
。
您可以定义属性更改行为,并使用对象列表来应用它。
如果在编译时已经知道需要哪些属性和哪些值,则可以创建一个lambda并将其传递给周围。
// Define the behavior and get the object list
Action<Something> setter = o => o.Someflag = true;
var objectList = new List<Something>();
// Call your processing method later on
SetProperties(objectList, setter);
void SetProperties<T>(List<T> objects, Action<T> setter)
{
objects.ForEach(setter);
}
如果您不知道在编译时需要哪些属性和值,那么事情就变得复杂得多。您将需要使用Reflection获取属性描述符并设置值。
这是一个简化的示例:
// Define the behavior and get the object list
var objectList = new List<Something>();
string propertyName = "SomeFlag";
PropertyInfo pi = typeof(Something).GetProperty(propertyName);
MethodInfo setter = pi.GetSetMethod();
object value = true;
// Call your processing method later on
SetProperties(objectList, setter, value);
void SetProperties<T>(List<T> objects, MethodInfo setter, object value)
{
var arguments = new object[] { value } ;
objects.ForEach(o => setter.Invoke(o, arguments));
}