首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >静态IEnumerable?

静态IEnumerable?
EN

Stack Overflow用户
提问于 2010-10-10 00:50:59
回答 4查看 10.4K关注 0票数 4

我在试着用弦乐来表达自己的想法。到目前为止,我得到的是,

代码语言:javascript
复制
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)除非实例化它,否则它是不可枚举的,这是我不需要也不想做的。我有什么选择?忘了让它是可枚举的?

我想这是我所能得到的

代码语言:javascript
复制
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()方法放在一个子类中:

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-10-10 02:07:59

哈哈!解决了!

代码语言:javascript
复制
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即可。

票数 3
EN

Stack Overflow用户

发布于 2010-10-10 01:39:19

我从您的Combinator类中删除了继承

代码语言:javascript
复制
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关键字。

静态实现

用法:迭代静态类字段,并收集输出:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();
foreach ( var ch in Util.AsEnumerable<char>(typeof(Combinators)) )
        sb.AppendLine(ch.ToString());

实现:一个C#迭代器来简化这个特性(它重新研究了一些原始代码):

代码语言:javascript
复制
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中收集结果:

代码语言:javascript
复制
StringBuilder sb = new StringBuilder();
foreach (var ch in new Combinators().AsEnumerable<char>())
    sb.AppendLine(ch.ToString());

实现: C# 可拓法到faciliate实例枚举:

代码语言:javascript
复制
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;
    }

}
票数 2
EN

Stack Overflow用户

发布于 2010-10-10 00:58:06

不创建实例是不可能的--类型本身无法实现接口。最好的选择是

代码语言:javascript
复制
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编写一个扩展。

代码语言:javascript
复制
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>()一样使用它

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3898515

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档