创建由对象属性引用组成的列表

时间:2019-09-06 12:02:18

标签: c# list object reference

我正在尝试执行以下操作:
-从第一种方法中,我要遍历一堆(相同类型的)对象,并将指向特定属性的指针提取到列表中
-此列表将在某个时间点馈入程序其他位置的另一种方法,并且必须修改原始对象的所有属性(按照提供的列表)

换句话说,我们有以下课程:

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;
}

2 个答案:

答案 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>()中,您可以存储对对象的引用。

请注意,虽然对于值类型来说这是不可能的。如果Somethingstruct,而不是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));
}