2012-11-21 153 views
0

我有CParam的詞典與註冊爲重點,變量名字符串

CParam具有從外部文本文件中讀取並說明作爲一個關鍵的HumanDesc讀一個字段。

文本文件是一個翻譯文件,描述必須是一個字符串。 像這樣

PLACE_HOLDER1 "First Place where things are put" 
PLACE_HOLDER2 "Secod Place where things are put" 
..... 

我可以很容易地通過將註冊成爲和把它放在引號做到這一點。但有一個100註冊,這將是乏味的(而不是非常優雅)。 有沒有一種方法,構造函數可以爲我處理。

下面是什麼我是個嘗試做一個很簡單的例子:

using System; 
using System.Collections.Generic; 
namespace Var2String 
{ 
    public class CParam 
    { 
    public ushort Register; 
    public string Description; 
    public ushort Content; 
    public string HumanDesc; 
    public CParam(ushort t_Register, string t_Description, string t_HumanDesc, ushort DefaultVal) 
    { 
     Register = t_Register; 
     Description = t_Description; 
     Content = DefaultVal; 
     HumanDesc = t_HumanDesc; 
    } 
}; 

static class Device1 
{ 
    public const ushort PLACE_HOLDER1 = 0x0123; 
    public const ushort PLACE_HOLDER2 = 0x0125; 
    public const ushort PLACE_HOLDER_SAME_AS_1 = 0x0123; 
    public static Dictionary<ushort, CParam> Registers; 
    static Device1() 
    { 
     Registers = new Dictionary<ushort, CParam>() 
    { 
     {PLACE_HOLDER1, new CParam(PLACE_HOLDER1,"PLACE_HOLDER1","Place One Holder",100)}, 
     {PLACE_HOLDER2, new CParam(PLACE_HOLDER1,"PLACE_HOLDER2","Place Two Holder",200)} 
    }; 
     /* 
     * Like to be able to do this 
     * And constructor CParam 
      Registers = new Dictionary<ushort, CParam>() 
    { 
     {PLACE_HOLDER1, new CParam(PLACE_HOLDER1,"Place One Holder",100)}, 
     {PLACE_HOLDER2, new CParam(PLACE_HOLDER1,"Place Two Holder",200)} 
    }; 
     */ 
    } 

} 
class Program 
{ 
    static private string LookUpTranslationFor(string Key) 
    { 
     string Translated = "Could not find Val for " + Key; 
     //This would read XML file use Key to get translation 
     return Translated; 
    } 
    static void Main(string[] args) 
    { 
     Console.WriteLine(Device1.Registers[Device1.PLACE_HOLDER1].HumanDesc); 
     Console.WriteLine(Device1.Registers[Device1.PLACE_HOLDER2].HumanDesc); 
     Device1.Registers[Device1.PLACE_HOLDER2].HumanDesc = LookUpTranslationFor(Device1.Registers[Device1.PLACE_HOLDER2].Description); 
     Console.WriteLine(Device1.Registers[Device1.PLACE_HOLDER2].HumanDesc); 
     Console.ReadKey(true); 
    } 
} 

}

回答

2

我不知道我理解你的權利,但如果你註冊的變量不是const的,你可以做這樣的事情:

1.增加其它構造函數來CParam

public class CParam 
{ 
    .... 

    public CParam(Expression<Func<ushort>> ex, string t_HumanDesc, ushort DefaultVal) 
    { 
     Content = DefaultVal; 
     HumanDesc = t_HumanDesc; 
     Description = ((MemberExpression) ex.Body).Member.Name; 
     Register = ex.Compile().Invoke(); 
    } 
}; 

2。 CHAGE您的設備類是這樣的:

internal static class Device1 
{ 
    public static ushort PLACE_HOLDER1 = 0x0123; 
    public static ushort PLACE_HOLDER2 = 0x0125; 
    public static ushort PLACE_HOLDER_SAME_AS_1 = 0x0123; 
    public static Dictionary<ushort, CParam> Registers; 

    static Device1() 
    { 
     Registers = new Dictionary<ushort, CParam>() 
         { 
          {PLACE_HOLDER1, new CParam(() => PLACE_HOLDER1, "Place One Holder", 100)}, 
          {PLACE_HOLDER2, new CParam(() => PLACE_HOLDER1, "Place Two Holder", 200)} 
         }; 
    } 
} 

注意事項是什麼不會與常量變量的工作!

+0

是的,這將做到這一點。我在進入Exression之前,正試圖避免使用Linq也PLACE_HOLDERS1無法更改。但是否則這是行得通的,如果我找不到其他解決方案,我會使用它。 –

+0

您只能使PLACE_HOLDER1只讀,所以沒有人可以更改它。 – HoberMellow

+0

我無法在case語句中使用readonly,並且在現有代碼中的很多地方使用case。 –

0

得到你需要使用反射類,但你不能使用反思值類型變量名

0

您可以使用Reflection.Emit構建一個包含所需屬性的類,但對我來說,它感覺很不舒服,而且由於會在運行時生成成員(導致您使用字符串時出現同樣的問題),所以缺少IntelliSense。

如果文件結構是可靠的並且可以依賴,爲什麼不創建一個從配置文件生成類文件的小工具?然後,您可以使用該類作爲佔位符,在運行時使用配置文件中的數據填充成員(使用反射將類中的屬性映射到文件中的屬性),或者直接在類中設置數據。

然後,您可以將此配置類添加到您的項目中,並根據需要將其轉換爲字典。