2

C# では、特定のクラスの静的フィールドを定義しています。クラス内から、次のように静的フィールドの名前を表示できるようにしたいと考えています。

public class Unit {
  public string NameOfField { get { return ...; } }
}

public static Unit Hectare = new Unit();

私が今アクセスした場合:

Hectare.NameOfField

私はそれを返したい:

Hectare

静的関数 System.Reflection.MethodBase.GetCurrentMethod() があることは知っていますが、私が知る限り、この現在のメソッドを含むインスタンスの名前を取得する方法はありませんか?

System.RuntimeFieldHandle 構造もありますが、GetCurrentFieldHandle() メソッドを特定できませんでした。

明らかな何かが欠けているかどうかわかりませんか?

これに関するヘルプは大歓迎です。

4

4 に答える 4

1

変数名は実行時に終了しないため、開発では変数名を当てにしないでください。

Unit を名前で直接初期化することをお勧めします。

public class Unit {

  public Unit(string name)
  {
     NameOfField = name;
  }
  public string NameOfField { get; private set;} }
}

public static Unit Hectare = new Unit("Hectare");
于 2011-04-05T09:20:18.097 に答える
0

Reflection を使用して、クラスのフィールドとプロパティを取得できます。以下のように:

1 つのプロパティを持つクラスがあるとします。

class Test
{
    public static string MySupperField
    {
        get
        {
            return "Some symbols here";
        }
    }
}

......

プロパティ名は次のように読み取ることができます。

public string[] GetClassStaticNames(Type T)
{
    string[] names;

    System.Reflection.PropertyInfo[] props = T.GetProperties(); // This will return only properties not fields! For fields obtaining use T.GetFields();

    names = new string[props.Count()];
    for (int i = 0; i < props.Count(); i++)
    {
        names[i] = props[i].Name;
    }

    return names;
}

これが役立つことを願っています。

[編集]
質問に戻る - いいえ、現在の変数の名前を取得できません。
クラスの性質上、あなたが求めていることはできません.それらはメモリ内のオブジェクトであり、1つのオブジェクトへの参照は多くの変数に保持できます.インスタンスフィールドまたはプロパティの値を要求している場合、実際にはオブジェクトで操作が実行されます.そのオブジェクトへの参照を保持する変数を持たないメモリ。したがって、現在のインスタンスへの参照を保持する変数の名前を取得しても意味がありません

于 2011-04-05T09:37:07.173 に答える
0

これを回避する唯一の方法は、その情報をクラスに保存することです。

public static Unit Hectare = new Unit("Hectare");

コードがコンパイルされると、すべての変数名が失われ、内部参照に置き換えられます。その名前を再び取得する方法はありません。

于 2011-04-05T09:22:10.383 に答える
0

私の質問に答えて議論するために時間を割いてくれたすべての人に感謝します.

お知らせするために、私のニーズに十分なソリューションを実装しました。解決策は一般的ではなく、いくつかの落とし穴がありますが、他の人の助けになる場合に備えて、とにかく共有すると思いました.

原則として、フィールドを定義するときに使用されるクラスは次のようになります。

public class Unit : IUnit {
  public NameOfField { get; set; }
  ...
}

ご覧のとおり、このクラスは IUnit インターフェイスを実装しており、NameOfField プロパティにパブリック セッターを提供しています。

静的フィールドは通常、いくつかの包含クラス内で次のように定義されます。

public static Unit Hectare = new Unit();

私の解決策は、フィールドが実装で使用される前に、リフレクションを通じて NameOfField プロパティを設定することです。これは、静的コンストラクターを介して行います (もちろん、Unit フィールドにアクセスする前に呼び出す必要があります。Linq を使用して、関連するフィールドの実行中のアセンブリをトラバースし、これらのフィールド (型が IUnit インターフェイスを実装するフィールド) を検出した場合) )、Any 拡張メソッドを使用して、それぞれに NameOfField プロパティを設定します。

Assembly.GetExecutingAssembly().GetTypes().
  SelectMany(type => type.GetFields(BindingFlags.Public | BindingFlags.Static)).
  Where(fieldInfo => fieldInfo.FieldType.GetInterfaces().Contains(typeof(IUnit))).
  Any(fieldInfo =>
  {
    ((IUnit)fieldInfo.GetValue(null)).NameOfField= fieldInfo.Name;
    return false;
  });

このアプローチにはいくつかの欠点があります。

  • Unit フィールドにアクセスする前に、静的コンストラクターを手動で呼び出す必要があります。
  • NameOfField セッターはパブリックです。私の場合は問題ありませんが、他のシナリオで適用する場合は問題になる可能性があります。(セッターを非公開にして、さらに検討することで呼び出すことができると思いますが、その道をさらに探求する時間は取っていません。)
  • ... ?

いずれにせよ、この解決策は私以外の誰かに役立つかもしれません.

于 2011-04-05T20:17:23.267 に答える