2012-11-01 73 views
2

我用常量字符串創建了一類類(顯示其中的一個類),我想對其進行操作。使用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())); 
    } 
} 

上面的代碼顯示了我的嘗試,但即使經過大量的試驗和錯誤,我仍然無法做到正確。

我想列出所有列作爲常量集合數組或列表。

回答

5
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(); 
+0

哇......我正要對你的第一個答案發表評論,不關注69個其他「表格」信息的存在。所以使用[0]是不夠的,但在最後一個答案中,你已經使它完美和真實夏普(短)我現在要測試它!歡呼聲 – LoneXcoder

+0

作品魅力!雖然如果我對字典不感興趣,(我會在不同的值和名稱的情況下保留這個),在這種情況下,我想得到任何(一個)你是否可以舉一個例子? – LoneXcoder

+0

@LoneXcoder我不確定我解決了你的問題。你需要一個清單嗎?我更新了答案。 –

1

它看起來像你需要的是一個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; 
    } 
} 
+0

謝謝你,雖然如果我不得不選擇其中的一個,我會選擇它,因爲它是一個密封類中的常量字符串,所以我可以在「單一」模式下訪問它: 'var Name = Assistant.UserName;' – LoneXcoder

+0

@LoneXcoder你可以這樣做,它只是:'string name = Assistant.UserName.ToString();'。另外,如果你真的想要更強大的解決方案,請參閱編輯。 – Servy

+0

對不起,雖然我討厭Tostring,當它是一個字符串,如果我可以讓你不要說我的觀點,那只是我這樣想的,我儘量做到光滑 – LoneXcoder