使用反射修改集合项?

Modify collection items using reflection?

我想使用反射按名称查找集合 (MyAssembly.Constants.MyCollection),检查其项 (List<string>),如果项不存在则添加项。到目前为止,我能够找到该集合并查看其项目,但需要帮助将缺失值添加到真实集合中。这是我目前所拥有的:

var assembly = Assembly.Load("MyAssembly");
var constants = assembly.GetType("MyAssembly.Constants");
var myCollection = constants.GetField("MyCollection").GetValue(null) as List<string>;

if (!myCollection.Contains("some_value"))
{
     //Add the missing item to MyAssembly.Constants.MyCollection
}

readonly 仅适用于该字段,意味着您不能为其分配另一个(或相同的)集合实例或 null。这并不意味着该集合本身是一个只读集合。

因为您有一个类型为 List<string> 的变量 myCollection,所以您不需要反射。随便写

myCollection.Add("some value"); // allowed.

请注意 List<T> 是 class,因此是 引用类型 。即,变量 myCollection 包含对 real 集合的 referencemyCollection.Add("some value"); 将新值添加到 real 集合 (MyAssembly.Constants.MyCollection)!

但由于 readonly 关键字,不允许像 Constants.MyCollection = null; 这样的内容。

示例:

static readonly List<string> myCollection = new List<string>();
static ReadOnlyCollection<string> roc = new ReadOnlyCollection<string>(myCollection);

readonly 字段或属性可以用初始化表达式或在构造函数中初始化。鉴于上述声明:

myCollection.Add("text"); // OK, collection not readonly.
myCollection = new List<string>(); // NOT POSSIBLE, field readonly.

roc.Add("text"); // NOT POSSIBLE, readonly collection has no Add method.
roc = new ReadOnlyCollection<string>(new[] { "a", "b" }); // OK, roc field not readonly.

static并不意味着字段或集合不能更改。这意味着该字段不是必须通过class实例(对象)引用的实例字段,而是属于class并且可以通过class名称访问.

示例:

class MyClass
{
    public static int staticField;
    public        int instanceField;
}

鉴于上面的声明:

var obj = new MyClass();
var x = obj.instanceField;    // OK
var y = MyClass.staticField;  // OK

var z = MyClass.instanceField; // DOES NOT COMPILE!
// CS0120: An object reference is required for the nonstatic field, method, or property 
//         'MyClass.instanceField'

var t = obj.staticField;       // DOES NOT COMPILE!
// CS0176: Static member 'MyClass.staticField' cannot be accessed with an instance
//         reference; qualify it with a type name instead