问题描述
我想使用反射按名称 (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
。这并不意味着集合本身就是一个只读集合。
由于变量 myCollection
的类型为 List<string>
,因此不需要反射。随便写
myCollection.Add("some value"); // allowed.
请注意,List<T>
是一个类,因此是一个引用类型。即,变量 myCollection
包含对 真实 集合的引用。 myCollection.Add("some value");
将新值添加到 real 集合 (MyAssembly.Constants.MyCollection
)!
但由于 Constants.MyCollection = null;
关键字,不允许使用 readonly
之类的内容。
示例:
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 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