0

.Net 4.5 で作業しています。

ActiveX コントロール (具体的には CadCorp SIS activeX コントロール) をカプセル化するクラスを作成し、基本的にそのコントロールの内部で使用可能なオブジェクトの一部を複製します (ただし、外部では使用できません)。内部オブジェクトのプロパティは、テキスト文字列を受け取る API を使用して外部から操作する必要があります。

各クラスで、APIを介して値を取得および設定するためのプロパティを作成することになり、基本的に同じコードを何度も繰り返します。たとえばControl.GetInt(TargetDescripor, TargetIdentifier, PropertyName);、ジェネリックを使用してコードを最小限に抑えようとしています。私は今、このような方法を持っています:

public T GetPropertyValue<T>(ObjectTypes Target, string PropertyName, int TargetIdentifier = 0)

正しい API メソッドを識別し、必要な値を返します。

正しい記述子と正しいプロパティ名を使用して、すべてのオブジェクトからこのメソッドを呼び出す必要があります。私はそれをさらに減らしました。たとえば、オブジェクトの 1 つでプロパティを取得する場合、次のコードを使用します。

public Class MyObject
{
    public bool MyObjectPropertyX
    {
        get { return this.GetProperty<bool>(); }
    }

    private const string _MyObjectPropertyX = "APICommandString";

    private T GetPropertyValue<T>([CallerMemberName] string PropertyName = null)
    {
        string apiCommand = (string)this.GetType().GetField("_" + PropertyName, BindingFlags.NonPublic | BindingFlags.Static).GetValue(this);

        // Call the method which executes the API command with the correct object
        // descriptor and get the value
    }
}

これはうまく機能します。

this.GetProperty<T>()プロパティのゲッターで、型パラメータがプロパティの型に自動的に設定された状態で を呼び出すことができるかどうか疑問に思っています。それは実現可能ですか?それとも、私が今持っているものは、それが得るのと同じくらい良いですか?

アップデート

また、この種の方法に移行することの欠点があるかどうかも知りたいです。多くの API 呼び出しを行う必要があるため、リフレクションを使用すると、各ゲッターとセッターで適切なメソッドを明示的に呼び出した元のコードと比較して、実際にこれが遅くなるかどうか疑問に思っていますか?

4

1 に答える 1

1

get最初のポイントに対処するために、物事を複雑にしすぎずにコードをさらに削減するとは思いません。タイプを指定するだけで問題ないようです。

文字列をハードコーディングせずにプロパティ名を特定できるようにする場合は、このメソッドをリフレクションで使用できます。

パフォーマンスに関しては、何よりも次のように言います。テストしてください。遅い場合は、プロパティ アクションのルックアップをキャッシュしてみてください。このコードは、リフレクション ルックアップが毎回必要とされないように、リフレクトされfield.getValueた呼び出しをラップします。Func<string>いずれにせよ、リフレクション API は内部的にキャッシュを行うため、これによるメリットはほとんどないことに注意してください。

    private readonly IDictionary<String, Func<String>> _cache = new Dictionary<String, Func<String>>();

    private String GetApiCommand(String propertyName)
    {
        Func<String> command;
        if (_cache.TryGetValue(propertyName, out command))
        {
            return command();
        }

        var field = GetType().GetField("_" + propertyName, BindingFlags.NonPublic | BindingFlags.Static);//.GetValue(this);

        if (field != null)
        {
            Func<String> action = () => (String)field.GetValue(this);
            _cache[propertyName] = action;

            return action();
        }

        throw new NotSupportedException();
    }
于 2013-03-28T10:45:29.003 に答える