固定容器,可枚举,intellisense可索引(或成员)
本文关键字:成员 索引 枚举 intellisense | 更新日期: 2023-09-27 18:20:49
我正在尝试创建一个对象来容纳一些字符串。对象可以是任何东西,包括集合、数组。。。字符串需要是可枚举的(IEnumerable或类似)。每个字符串索引器都需要intellisense知道,Reflection是最后一个选项。一个单独的对象,索引器没有单独的对象。
示例用法:
public static class features
{
public const string favorite = "blue background";
public const string nice = "animation";
}
public static class Program
{
public static void Main()
{
foreach (string feature in features)
{
Console.WriteLine(feature);
}
//... select a feature
Console.WriteLine(features.favorite);
}
}
编辑:我将使用Jim Mischel提出的第一个解决方案,该解决方案被修改为使用反射,因为这获得了我目前感兴趣的优势。
- 将所有内容封装在一个实体中
- 名称与值直接相关
枚举器是动态
public IEnumerator<string> GetEnumerator() { FieldInfo[] strings = this.GetType().GetFields(); foreach (FieldInfo currentField in strings) { yield return currentField.GetValue(null).ToString(); } yield break; }
我感谢大家的努力。
我可以想出两种方法。但是,由于它必须是IEnumerable<string>
,所以它不能是静态类,因为静态类不能实现接口。静态方法也不能实现接口方法。
第一种方法使用常量和只按顺序返回它们的枚举器:
public class Features: IEnumerable<string>
{
public const string Favorite = "blue background";
public const string Nice = "animation";
public IEnumerator<string> GetEnumerator()
{
yield return Favorite;
yield return Nice;
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
第二种方法将值存储在数组中,并使用enum
作为索引。枚举器只返回数组的枚举器。同样,这不是静态的,因为枚举器,也因为索引器不能是静态的。
public enum FeaturesIndex
{
Favorite = 0,
Nice = 1
}
public class Features2 : IEnumerable<string>
{
private static readonly string[] _features = new string[]
{
"blue background",
"animation"
};
public string this [FeaturesIndex ix]
{
get { return _features[(int) ix]; }
}
public IEnumerator<string> GetEnumerator()
{
return ((IEnumerable<string>) _features).GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
正如其他人所指出的,第三种可能性是使用字典和枚举或定义的常量作为键。这是一种有趣的方法,唯一的潜在缺点是无法保证枚举集合时返回键的顺序。如果这是一个问题,您可以让您的枚举器在返回之前对序列进行排序。
不管你怎么看,都有权衡。我的两个解决方案都需要手动同步密钥和值。在第一种情况下,您必须确保枚举器返回所有值。在第二个步骤中,您必须确保enum
与数组匹配。
拿起你的毒药。
这也取决于你将如何使用这个东西。我的第一个解决方案具有简单性的优点,如果它是一种写一次,永远使用的东西,可能会很容易被接受。第二个选项的好处是使用索引器,它通常与集合相关联。
有很多更好的方法可以做到这一点。为了遵循与你所寻找的相似的模式,这里有一种方法:
public static class features
{
public enum TYPES { favorite, nice }
public static Dictionary<TYPES,string> values = new Dictionary<TYPES,string>() {
{ TYPES.favorite, "blue background" },
{ TYPES.nice, "animation" } };
}
public static class Program
{
public static void Main()
{
foreach (string feature in features.values.keys)
{
Console.WriteLine(features.values[feature]);
}
//... select a feature
Console.WriteLine(features.values[TYPES.favorite]);
}
}
因此,您真正想要的是一个具有属性的对象,您可以更改该对象,该对象也是可枚举的,但它使您不需要调用反射来枚举,除非绝对必要。
如果我认为你实际看到的是以下
public class Features: IEnumerable<string>
{
private readonly Dictionary<string,string> _internalCollection;
public Features()
{
_internalCollection = new Dictionary<string,string>();
}
private string GetByKey(string id)
{
if(!_internalCollection.ContainsKey(id))
return null;
return _internalCollection[id];
}
private void SetByKey(string id, string value)
{
_internalCollection[id]=value;
}
const string _favoriteId = "favorite";
public string Favorite
{
get { return GetByKey(_favoriteId); }
set { return SetByKey(_favoriteId,value);}
}
const string _niceId = "nice";
public string Nice
{
get { return GetByKey(_niceId);}
set { return SetByKey(_niceId, value);}
}
public string this[string index]
{
get { return GetByKey(index.ToLower()); }
set { return SetByKey(index.ToLower(), value);}
}
public IEnumerator<string> GetEnumerator()
{
foreach(var key in _internalCollection.Keys)
yield return _internalCollection[key];
yield break;
}
}