0

レジスターをキーにしたCParamの辞書があります。

CParamには外部テキストファイルから読み取られるフィールドが1つあり、HumanDescで読み取るためのキーとしてDescriptionが使用されます。

テキストファイルは翻訳ファイルであり、説明は文字列である必要があります。このようなもの

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

Register asを挿入し、引用符で囲むことで、これを簡単に行うことができます。しかし、何百ものレジスターがあり、それは退屈です(そしてあまりエレガントではありません)。コンストラクターが私のためにそれを処理できる方法はありますか?

以下は、私がやろうとしていることの非常に単純化された例です。

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

変数名を取得するには、Reflectionクラスを使用する必要がありますが、ReflectiononValueタイプを使用することはできません

于 2012-11-21T14:22:15.187 に答える
0

を使用して目的のプロパティを含むクラスを作成することもできReflection.Emitますが、メンバーは実行時に生成されるため(文字列を使用する場合と同じ問題が発生するため)、ハッキーな感じがし、IntelliSenseが不足します。

ファイル構造がしっかりしていて信頼できる場合は、構成ファイルからクラスファイルを生成する小さなユーティリティを作成してみませんか?次に、クラスをプレースホルダーとして使用して、実行時に構成ファイルのデータをメンバーに入力するか(Reflectionを使用してクラスのプロパティをファイルのプロパティにマップする)、クラスのデータを直接設定できます。

次に、この構成クラスをプロジェクトに追加し、必要に応じて辞書に変換できます。

于 2012-11-21T14:22:17.257 に答える