Использование System.Reflection для получения списка полей константных строк
Я создал класс классов (показывающий один из них) с константной строкой, которую я хочу использовать.
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()));
}
}
Приведенный выше код показывает мою попытку, но даже после множества проб и ошибок я все равно не смог сделать это правильно.
Я хочу иметь список всех столбцов в виде константного массива или списка.
2 ответа
var dict = typeof(HTDB_Cols).GetNestedTypes()
.First(t=>String.Compare(t.Name,TableName,true)==0)
.GetFields()
.ToDictionary(f => f.Name, f => f.GetValue(null));
Чтобы получить список
var list = typeof(HTDB_Cols).GetNestedTypes()
.First(t => String.Compare(t.Name, TableName, true) == 0)
.GetFields()
.Select(f => f.GetValue(null) as string)
.ToList();
Похоже, что вам нужно это enum
:
enum Assistant
{
EntryID,
CustName,
SerialNum,
UserName,
Password,
EndDate,
CustID,
TmpCheck,
Isfamily,
Isserver
};
Затем вы можете получить все эти имена в виде строк, выполнив:
string[] allNames = Enum.GetNames(typeof(Assistant));
Если для вас допустимо, чтобы имена переменных были фактическими значениями, которые вас интересуют, это допустимый вариант. Я отмечаю, что они не совсем одинаковы в вашем примере, но в основном это просто корпус. Если вы можете использовать имена переменных в качестве значений или изменить имена переменных на нужные значения, то это, вероятно, будет вашим лучшим вариантом.
Теперь, если действительно важно, чтобы имена переменных отличались от значений, которые они представляют, или если вам нужно представлять значения, которые являются недопустимыми идентификаторами (например, у одного из ваших значений есть пробел, это бесполезно, и они не могут никогда не начинайте с цифры, или они могут быть слишком длинными, чтобы быть удобным именем). Если это так, то то, что вам действительно нужно, это перечисление, которое поддерживается строкой, а не целое число или другой числовой тип. Это не совсем возможно в C#, но так как это произошло до того, как я действительно написал следующий класс, это моя лучшая попытка создания моего собственного перечисления на основе строки. Если вам действительно нужны имена переменных, которые отличаются от строковых значений, которые они представляют, это должно работать для вас.
Все важные вещи прямо наверху, большинство всего после Equals
это просто синтаксический сахар.
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;
}
}