我在试着用弦乐来表达自己的想法。到目前为止,我得到的是,
private class TypedEnum<T> : IEnumerable<T>
{
public IEnumerator<T> GetEnumerator()
{
return GetType().GetFields().Where(f => f.IsLiteral).Select(f => f.GetValue(null)).OfType<T>().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
private static class Combinators : TypedEnum<char>
{
public const char DirectChild = '>';
public const char NextAdjacent = '+';
public const char NextSiblings = '~';
public const char Descendant = ' ';
}但这有两个问题。(1)它不会编译,因为Combinators是静态的。不过,我可以把它移开藏起来。(2)除非实例化它,否则它是不可枚举的,这是我不需要也不想做的。我有什么选择?忘了让它是可枚举的?
我想这是我所能得到的
public struct Combinators
{
public const char DirectChild = '>';
public const char NextAdjacent = '+';
public const char NextSiblings = '~';
public const char Descendant = ' ';
public static IEnumerable<char> ToEnumerable()
{
return typeof(Combinators).GetFields().Where(f => f.IsLiteral)
.Select(f => f.GetValue(null)).OfType<char>();
}
}但是我希望我能把这个ToEnumerable()方法放在一个子类中:
发布于 2010-10-10 02:07:59
哈哈!解决了!
public class TypedEnum<TBase, TValue>
{
public static IEnumerable<TValue> ToEnumerable()
{
return typeof (TBase).GetFields(BindingFlags.Public | BindingFlags.Static)
.Select(f => f.GetValue(null)).OfType<TValue>();
}
public static TValue[] ToArray()
{
return ToEnumerable().ToArray();
}
public static string Pattern
{
get
{
return string.Format("(?:{0})", string.Join("|", ToEnumerable().Select(c => Regex.Escape(c.ToString()))));
}
}
}
public class Combinators : TypedEnum<Combinators, char>
{
public const char DirectChild = '>';
public const char NextAdjacent = '+';
public const char NextSiblings = '~';
public const char Descendant = ' ';
}只需将类本身作为类型传递给TypedEnum即可。
发布于 2010-10-10 01:39:19
我从您的Combinator类中删除了继承
static class Combinators { // no inheritance注意:这些解决方案使用的http://msdn.microsoft.com/en-us/library/dscyy5s0.aspx比成熟的http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/191b9b61-b8c5-43b0-9c13-d1cf848d6c00实现更简单;迭代器只需要http://msdn.microsoft.com/en-us/library/9k7k7cf0.aspx关键字。
静态实现
用法:迭代静态类字段,并收集输出:
StringBuilder sb = new StringBuilder();
foreach ( var ch in Util.AsEnumerable<char>(typeof(Combinators)) )
sb.AppendLine(ch.ToString());实现:一个C#迭代器来简化这个特性(它重新研究了一些原始代码):
static public class Util {
static public IEnumerable<T> AsEnumerable<T>(Type t)
{
if (ReferenceEquals(null, t))
yield break;
foreach (T val in t.GetFields().Where(f => f.IsLiteral).Select(f => f.GetValue(null)).OfType<T>())
yield return val;
}
}结果
接收Combinator类字段的StringBuilder的结果如下:
+ ~ (空间)
实例实现
(__注意:-不需要回答这个问题,而是为后代添加,作为上面所示静态方法的对应物)
USAGE:作为对任何实例的扩展调用的方法,在StringBuilder中收集结果:
StringBuilder sb = new StringBuilder();
foreach (var ch in new Combinators().AsEnumerable<char>())
sb.AppendLine(ch.ToString());实现: C# 可拓法到faciliate实例枚举:
static public class EXTENSIONS
{
static public IEnumerable<T> AsEnumerable<T>(this object thisObj) {
if (ReferenceEquals(null, thisObj))
yield break;
foreach (T val in thisObj.GetType().GetFields().Where(f => f.IsLiteral).Select(f => f.GetValue(null)).OfType<T>())
yield return val;
}
}发布于 2010-10-10 00:58:06
不创建实例是不可能的--类型本身无法实现接口。最好的选择是
private class Combinators : TypedEnum<char>
{
public static readonly Combinators Instance = new Combinators();
private Combinators()
{
}
public const char DirectChild = '>';
public const char NextAdjacent = '+';
public const char NextSiblings = '~';
public const char Descendant = ' ';
}因此,您将拥有一个实例,这些实例可以被枚举、传递给方法等。
或者,您可以为Type编写一个扩展。
public static class TypeExtensions
{
public static IEnumerable<T> EnumerateConstantFields<T>(this Type type)
{
return type.GetFields().Where(f => f.IsLiteral).Select(f => f.GetValue(null)).OfType<T>();
}
}并像使用typeof(Combinators).EnumerateConstantFields<char>()一样使用它
https://stackoverflow.com/questions/3898515
复制相似问题