0

我有一个 CParam 字典,其中注册为键,

CParam 有一个从外部文本文件中读取的字段,Description 用作在 HumanDesc 中读取的键。

文本文件是翻译文件,描述必须是字符串。像这样的东西

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

我可以通过插入 Register as 并将其放在引号中轻松地做到这一点。但是有一个 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);
    }
}

}

4

3 回答 3

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.像这样更改您的设备类:

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

请注意这不适用于 const 变量!

于 2012-11-21T14:43:36.273 回答
0

要获取变量名,您需要使用反射类,但不能对值类型使用反射

于 2012-11-21T14:22:15.187 回答
0

您可以使用 构建一个包含所需属性的类Reflection.Emit,但对我来说它感觉很笨拙,并且您将缺少 IntelliSense,因为成员将在运行时生成(导致与使用字符串相同的问题)。

如果文件结构可靠并且可以依赖,为什么不创建一个从配置文件生成类文件的小实用程序呢?然后,您可以使用类作为占位符,在运行时使用配置文件中的数据填充成员(使用反射将类中的属性映射到文件中的属性),或者直接在类中设置数据。

然后,您可以将此配置类添加到您的项目中,并在需要时将其转换为字典。

于 2012-11-21T14:22:17.257 回答