这与 Linq 动态查询单元没有任何关系。该单元适用于您拥有实际字段/属性的情况,并且它们的名称将在运行时提供给您。换句话说,你有一个这样的类:
public class Person
{
public int ID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
}
您希望能够编写这样的查询:
var sortedPeople = people.OrderBy("FirstName");
你正试图做与此完全相反的事情——你有一个没有任何实际属性的类,只有一个属性字典,并且你想要编译时安全。你不能拥有它;无法保证某个项目会在字典中,尤其是当字典是公开的并且任何人都可以直接从中添加/删除时!
如果出于某种原因您必须使用特定的类设计,那么您可以想象尼克提出的一些包装器,但我什至不会打扰 - 它们实际上并没有提供任何封装,因为Data
字典仍然对全世界。相反,我将只提供一个安全的getter 方法或索引器属性,并使用您希望其中的属性名称创建一些常量(或枚举)。
public class Item
{
public Dictionary<string, string> Data { get; set; }
public string GetValue(string key)
{
if (Data == null)
return null;
string result;
Data.TryGetValue(key, out result);
return result;
}
}
public class ItemKeys
{
public const string Name = "Name";
public const string Foo = "Foo";
}
等等。真的ItemKeys
不是那么重要,安全的GetValue
方法才是最重要的,因为否则你会冒一个NullReferenceException
ifData
没有被分配的风险,或者一个KeyNotFoundException
if甚至一个Item
实例都没有那个属性。GetValue
无论如何使用这里的方法都会成功:
var myItems = items.OrderBy(i => i.GetValue(ItemKeys.Name));
如果你发现你正在为相同的属性编写大量重复的代码,那么就开始担心向类中添加快捷方式属性或扩展方法。