Pergunta

I've created a class of classes (showing one of them) with const string that I want to itarate on.

public static class HTDB_Cols
{
    public sealed class Assistant
    {
        public const string EntryID  = "entryID",
                CustName  = "custName",
                SerialNum  = "serialNum",
                UserName  = "userName",
                Password  = "password",
                EndDate  = "end_date",
                CustID  = "custID",
                TmpCheck  = "tmpCheck",
                Isfamily  = "isfamily",
                Isserver  = "isserver";
    }
}               

public static class DB
{    
    public static void insert(string TableName)
    {
        ColumnsCollection = typeof(HTDB_Cols).GetNestedTypes().Where(f => f.DeclaringType.Name.ToLower().Equals(TableName.ToLower()));
    } 
}

The code above shows my attempt, but even after lots of trial and error I still couldn't get it right.

I want to have a list of all columns as const collection array or list.

Foi útil?

Solução

var dict = typeof(HTDB_Cols).GetNestedTypes()
            .First(t=>String.Compare(t.Name,TableName,true)==0)
            .GetFields()
            .ToDictionary(f => f.Name, f => f.GetValue(null));

To get a list

var list = typeof(HTDB_Cols).GetNestedTypes()
            .First(t => String.Compare(t.Name, TableName, true) == 0)
            .GetFields()
            .Select(f => f.GetValue(null) as string)
            .ToList();

Outras dicas

It looks like what you need is an enum:

enum Assistant
{
    EntryID,
    CustName,
    SerialNum,
    UserName,
    Password,
    EndDate,
    CustID,
    TmpCheck,
    Isfamily,
    Isserver
};

You can then get all of those names as strings by doing:

string[] allNames = Enum.GetNames(typeof(Assistant));

As long as it's acceptable for you to have the names of the variables be the actual values that you care about, that's a valid option. I note that they're not quite the same in your example, but it's mostly just casing. If you can deal with using the variable names as the values, or changing the variable names to be the values you need, then that's likely to be your best option.

Now, if it really is important for the variable names to be different than the values they represent, or if you need to represent values that are illegal identifiers (for example, one of your values has a space, that's no good, and they couldn't ever start with a digit, or they might just be too long to be a convenient name). If that's the case, then what you really want is an enum that's backed by a string, rather than an integer or other numeric type. That's not strictly possible in C#, but since this has come up before I actually wrote the following class which is my best attempt at creating my own string backed enum. If you really need variable names that differ from the string values they represent, this should work for you.

All of the important stuff is right at the top, most everything after Equals is just syntactic sugar.

public struct StringEnum
{
    #region Code that is to be configured
    //For each value to be publicly exposed add a new field.
    public static readonly StringEnum Alpha = new StringEnum("Alpha Value");
    public static readonly StringEnum Beta = new StringEnum("Beta Value");
    public static readonly StringEnum Invalid = new StringEnum("Invalid");


    public static IEnumerable<StringEnum> AllValues
    {
        get
        {
            yield return Alpha;
            yield return Beta;
            yield return Invalid;
            //...
            //add a yield return for all instances here.

            //TODO refactor to use reflection so it doesn't need to be manually updated.
        }
    }

    #endregion
    private string value;

    /// <summary>
    /// default constructor
    /// </summary>
    //private Group()
    //{
    //    //You can make this default value whatever you want.  null is another option I considered 
    //    //(if this is a class an not a struct), but you 
    //    //shouldn't have this be anything that doesn't exist as one of the options defined at the top of 
    //    //the page.
    //    value = "Invalid";
    //}
    /// <summary>
    /// primary constructor
    /// </summary>
    /// <param name="value">The string value that this is a wrapper for</param>
    private StringEnum(string value)
    {
        this.value = value;
    }

    /// <summary>
    /// Compares the StringEnum to another StringEnum, or to a string value.
    /// </summary>
    /// <param name="obj"></param>
    /// <returns></returns>
    public override bool Equals(object obj)
    {
        if (obj is StringEnum)
        {
            return this.Equals((StringEnum)obj);
        }

        string otherString = obj as string;
        if (otherString != null)
        {
            return this.Equals(otherString);
        }

        throw new ArgumentException("obj is neither a StringEnum nor a String");
    }

    /// <summary>
    /// Strongly typed equals method.
    /// </summary>
    /// <param name="other">Another StringEnum to compare this object to.</param>
    /// <returns>True if the objects are equal.</returns>
    public bool Equals(StringEnum other)
    {
        return value == other.value;
    }

    /// <summary>
    /// Equals method typed to a string.
    /// </summary>
    /// <param name="other">A string to compare this object to.  
    /// There must be a Group associated with that string.</param>
    /// <returns>True if 'other' represents the same Group as 'this'.</returns>
    public bool Equals(string other)
    {
        return value == other;
    }

    /// <summary>
    /// Overridden equals operator, for convenience.
    /// </summary>
    /// <param name="first"></param>
    /// <param name="second"></param>
    /// <returns>True if the objects are equal.</returns>
    public static bool operator ==(StringEnum first, StringEnum second)
    {
        return object.Equals(first, second);
    }

    public static bool operator !=(StringEnum first, StringEnum second)
    {
        return !object.Equals(first, second);
    }

    /// <summary>
    /// Properly overrides GetHashCode so that it returns the hash of the wrapped string.
    /// </summary>
    /// <returns></returns>
    public override int GetHashCode()
    {
        return value.GetHashCode();
    }

    /// <summary>
    /// returns the internal string that this is a wrapper for.
    /// </summary>
    /// <param name="stringEnum"></param>
    /// <returns></returns>
    public static implicit operator string(StringEnum stringEnum)
    {
        return stringEnum.value;
    }

    /// <summary>
    /// Parses a string and returns an instance that corresponds to it.
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    public static StringEnum Parse(string input)
    {
        return AllValues.Where(item => item.value == input).FirstOrDefault();
    }

    /// <summary>
    /// Syntatic sugar for the Parse method.
    /// </summary>
    /// <param name="other"></param>
    /// <returns></returns>
    public static explicit operator StringEnum(string other)
    {
        return Parse(other);
    }

    /// <summary>
    /// A string representation of this object.
    /// </summary>
    /// <returns></returns>
    public override string ToString()
    {
        return value;
    }
}
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top