質問
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;
}
}
}
}
}