我正在尝试使对象保持一些字符串。对象可以是任何东西,包括集合,数组......字符串需要可枚举(IEnumerable或类似)。每个字符串索引器都需要通过 intellisense 来识别,反射是最后一个选项。一个对象,没有单独的索引器对象。
使用示例:
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;
}
我感谢大家的努力。
答案 0 :(得分:2)
副手,我可以想到两种方法。但是,因为它必须是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
与数组匹配。
选择你的毒药。
这还取决于你将如何使用这件事。我的第一个解决方案具有简单的优点,如果它是一次写入,永久使用的东西,可能是完全可以接受的。第二种选择具有使用索引器的好处,索引器通常与集合相关联。
答案 1 :(得分:0)
有很多更好的方法可以做到这一点。要遵循与您正在寻找的类似的模式,这是一种方法:
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]);
}
}
答案 2 :(得分:0)
所以你要求的是一个对象,你可以改变属性并且也是可枚举的,但是除非绝对必要,否则你不需要调用反射来枚举。
如果我认为你实际上在寻找的是以下
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;
}
}