Static IEnumerable?

I am trying to do a line listing. That's what I still have

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 = ' ';
}

But there are two problems with this. (1) It will not compile because it Combinatorsis static ... I can remove this and hide c'tor. (2) This is not enumerable unless I create an instance that I do not need and do not want to do. What are my options? Forget about making it enumerable?


I think it is as close as I can get

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>();
    }
}

But I would like to add this method ToEnumerable()to a subclass: (

+3
source share
4 answers

Huh! I decided!

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 = ' ';
}

You just need to pass the class as type in TypedEnum.

+2
source

I removed the inheritance from the Combinators class

static class Combinators { // no inheritance

. # iterator, , Enumerator; yield.


: :

StringBuilder sb = new StringBuilder();
foreach ( var ch in Util.AsEnumerable<char>(typeof(Combinators)) )
        sb.AppendLine(ch.ToString());

: # ( ):

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;
    }
}

StringBuilder, Combinator:

>
+
~
()


( : - , , )

: , , StringBuilder:

StringBuilder sb = new StringBuilder();
foreach (var ch in new Combinators().AsEnumerable<char>())
    sb.AppendLine(ch.ToString());

: # :

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;
    }

}
+1

- . -

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>()

0

IEnumerable for-each. !

IEnumerable. , , , IEnumerable , .

If you have a reference to an array of your type, it is automatically IEnumerable. If you ever wanted to be able to run through the possible values ​​of your listing, this is another matter. You will create an array.

Example

public enum Operators
{
    Plus,
    Minus,
    Multiply,
    Divide,
    Power
}


string[] available_ops = Enum.GetNames(typeof(Operators));
foreach(string op in available_ops) //IEnumerable<string> working here
    Console.WriteLine("Available operator: {0}", op);

Output

    Available operator: Plus
    Available operator: Minus
    Available operator: Multiply
    Available operator: Divide
    Available operator: Power
-1
source

Source: https://habr.com/ru/post/1768804/


All Articles