c# - C# 为 ICollection 或 IEnumerable 中的特定项目创建 getter 委托
问题描述
我正在尝试创建一个动态Environment
类来托管模拟的实时数据。我希望能够注册特定的“环境变量”,例如集合、字段等。使用它,消费类将能够查看可用的变量并单独请求它们。
我想让这个基于反射的,以便任何未来的开发人员都可以采用现有的类并将其合并到其中,Environment
而无需实现其他功能。如果可能,我想添加对ICollection
和/或IEnumerable
接口的支持,以便可以使用实现这些的现有类。例如,能够注册 aDictionary
意味着环境会将所有键值对列为环境变量,其中键被转换为唯一的字符串,值是根据请求提供的值。
一个如何实现它的例子:
public class Environment
{
private delegate object GetterDelegate();
private Dictionary<string, GetterDelegate> environmentVariables_;
public IEnumerable<string> EnvironmentVariables
{
get => environmentVariables_.Keys;
}
public object this[string name]
{
get => environmentVariables_[name]();
}
public Environment()
{
environmentVariables_ = new Dictionary<string, GetterDelegate>();
}
public void Register( string name, ICollection collection )
{
int i = 0;
foreach( var element in collection )
environmentVariables_.Add( $"name_{i++}", GetterDelegate );
}
public void Register( string name, IEnumerable enumerable )
{
int i = 0;
foreach( var element in enumerable )
environmentVariables_.Add( $"name_{i++}", GetterDelegate );
}
public void Register<T,V>( string name, Dictionary<T,V> dictionary )
{
// TODO: Custom logic instead of Key.ToString()
foreach( var pair in dictionary )
environmentVariables_.Add( $"name_{pair.Key.ToString()}", GetterDelegate );
}
public void Register( string name, FieldInfo field )
{
environmentVariables_.Add( name, GetterDelegate );
}
}
为了实现这一点,我希望能够动态编译可以直接访问特定元素的 getter 方法,而不必IEnumerable.ElementAt()
每次都调用,因为这可能会非常慢,具体取决于类的实现。而且由于ICollection
implements IEnumerable
,在大多数情况下它可能会以相同的方式处理。
是否可以编译一个可以直接获取特定 IEnumerable 元素而无需调用 ElementAt() 的 DynamicMethod,这可能会枚举整个集合,直到找到合适的元素?如果这太迂回了,我也欢迎使用更好的方法来解决这个问题。
解决方案
IEnumerable
如果ICollection
您需要能够按索引访问项目,请不要使用。这些接口都不支持。
IList
是表示可以通过索引访问的数据的接口。
推荐阅读
- swift - 在我自己的框架中嵌入 Obj-C 框架
- datatable - jQuery datatable ajax 错误未命中服务器
- python - 使用访问令牌复制私有仓库的 .git(metadata) 文件夹
- sql - SQL 计算产品相同的客户
- c# - 删除 Grid 中 ImageButton 元素之间的空间
- python - 从特定的 HTML 元素、URL 列表中抓取文本,结合正则表达式,然后将它们连接到 .csv 中
- c# - 我的浏览器加载 CSS 时出现问题,我不知道该怎么办
- node.js - throw new Error('SASL: SCRAM-SERVER-FIRST-MESSAGE: 客户端密码必须是字符串'
- opengl - 当我单击它时,如何在 OpenGL/OpenTK 中显示三角形的长度?
- jquery - 使用 jQuery 滑动 Toogle 不流畅