質問

C#は、Pythonの__getattr__ようなものを持っていますか?

私は多くのプロパティを持つクラスを持っており、それらはすべて同じアクセサコードを共有しています。私はPythonで同じように、完全に個々のアクセサをドロップできるようにしたいと思います。

ここに私のコードは、今のようになります。

class Foo
{
    protected bool Get(string name, bool def)
    {
        try {
            return client.Get(name);
        } catch {
            return def;
        }
    }

    public bool Bar
    {
        get { return Get("bar", true); }
        set { client.Set("bar", value); }
    }

    public bool Baz
    {
        get { return Get("baz", false); }
        set { client.Set("baz", value); }
    }
}

そして、ここでは私が好きなものです。

class Foo
{
    public bool Get(string name)
    {
        try {
            return client.Get(name);
        } catch {
            // Look-up default value in hash table and return it
        }
    }

    public void Set(string name, object value)
    {
        client.Set(name, value)
    }
}

直接Getを呼び出すことなく、C#でこれを達成する方法はありますか?

おかげで、

役に立ちましたか?

解決

はありません。 C#は反射をサポートしていますが、それは読み取り専用です(ロードされたアセンブリのため)。それはあなたが任意のメソッド、プロパティ、またはその他のメタデータを変更することはできませんを意味します。あなたはではないでしょう、それを呼び出して、動的プロパティを作成することもできますが、非常に便利 - それはあなたのGetメソッドを使用するよりもさらに悪いことでしょう。別にDictionary<string, object>とあなたのクラスのインデクサを使用してから、あなたが行うことができます他の多くはありません。とにかく、あなたはその多くの性質を持っている場合は、より良い辞書をやっていないのですか?

属性は、「コンパイル時」(または少なくとも負荷時)に存在する場合は、

Pythonはチェックしません。 C#がありません。すなわち、2つの言語間の基本的な違いです。 Pythonでは、あなたが行うことができます:

class my_class:
    pass

my_instance = my_class()
my_instance.my_attr = 1
print(my_instance.my_attr)
名前my_attrは、コンパイル時に存在している場合はC#は、実際にチェックするため、

C#では、あなたはそれを行うことができないだろう。

他のヒント

私はわからないんだけど、多分、バージョン4.0の動的な特徴はそれでお手伝いをします。あなたがが待機する必要があります...

は、私が求めることができます:の理由のあなたは個々のプロパティをしたくないですか?つまり、オブジェクトに関連付けられたデータを表すの慣用NETの方法である。

個人的には、データがスパースでないと仮定すると、私は性質を維持し、全体的な方法の使用反射を持っているだろう - これは可能な限り迅速にあなたのコンパイルされたコードを作成します。

    protected T Get<T>(string name, T @default)
    {
        var prop = GetType().GetProperty(name);
        if(prop == null) return @default;
        return (T) prop.GetValue(this, null);
    }
あなた自身が定義されているプロパティを気にしない場合は、

もちろん、その後、インデクサーと(例えば、辞書など)ルックアップはOKだろう。あなたはプロパティバッグにプロパティのセットをオンにするpostsharpで行うことができるかもしれないものもあります - 。おそらくそれだけの価値はありません、しかしは、

あなたはデータバインディングと実行時の発見のためのプロパティが利用可能にしたいが、コンパイル時にそれらを定義することができない場合は、

、あなたはダイナミック型記述子を見てする必要があります。 ICustomTypeDescriptorまたはTypeDescriptionProviderのいずれか - 仕事の公平なビットが、非常に汎用性は、(あなたがより多くの情報が必要な場合は私に知らせて)

これは、動的なプロパティ名とPythonで得るものと同じではありませんが、あなたはそれが役に立つかもしれません。

using System;
using System.Collections.Generic;

namespace Program
{
    class Program
    {
        static void Main(string[] args)
        {
            MyList<int> list = new MyList<int>();
            // Add a property with setter.
            list["One"] = 1;
            // Add a property with getter which takes default value.
            int two = list["Two", 2];
            Console.WriteLine("One={0}", list["One"]);
            Console.WriteLine("Two={0} / {1}", two, list["Two"]);
            try
            {
                Console.WriteLine("Three={0}", list["Three"]);
            }
            catch
            {
                Console.WriteLine("Three does not exist.");
            }
        }
        class MyList<T>
        {
            Dictionary<string, T> dictionary = new Dictionary<string,T>();

            internal T this[string property, T def]
            {
                get
                {
                    T value;
                    if (!dictionary.TryGetValue(property, out value))
                        dictionary.Add(property, value = def);
                    return value;
                }
            }
            internal T this[string property]
            {
                get
                {
                    return dictionary[property];
                }
                set
                {
                    dictionary[property] = value;
                }
            }
        }
    }
}
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top