2

ここでは、名前を指定してクラスのプロパティの値を取得するためのソリューションが提供されています。今、私はこの状態で同じことをどのように行うことができるのだろうか:

MyClassクラスがあります。このクラスには、 fooという名前のFoo型のプロパティがあります。Fooには、barという名前のタイプBarのプロパティがあります。barにはvalueという名前の文字列プロパティがあります。

プロパティは静的ではありません。

文字列「foo.bar.value」をpropertyNameとして渡すことで、 foo.bar.valueの値を取得できるようにしたいと思います。つまり、プロパティパスを渡してその値を取得したいと思います。

出来ますか ?

4

4 に答える 4

5

これは再帰的な方法で行うことができます。各呼び出しは、パスの最初の単語を含む値を取得し、残りの部分を使用してメソッドを再度呼び出します。

public object GetPropertyValue(object o, string path)
{
    var propertyNames = path.Split('.');
    var value = o.GetType().GetProperty(propertyNames[0]).GetValue(o, null);

    if (propertyNames.Length == 1 || value == null)
        return value;
    else
    {
        return GetPropertyValue(value, path.Replace(propertyNames[0] + ".", ""));
    }
}
于 2012-08-27T11:44:10.643 に答える
4

これは、プロパティがクラスのように名前が付けられていることを前提としています。つまり、TypeのプロパティにFooも。という名前が付けられFooます。この仮定がなければ、問題はいくつかの重要な情報を欠いています。

string.Splitこのメソッドを使用foo.bar.valueして、ドットで文字列を区切ることができます。これで、プロパティ名ごとに1つの要素を持つ配列が作成されます。

その配列を繰り返し処理し、を使用PropertyInfo.GetValueしてプロパティの値を取得します。GetValue1回の操作で返される値は、次の反復で渡されるインスタンスです。

string props = "foo.bar.value";
object currentObject = // your MyClass instance

string[] propertyChain = props.Split('.');
foreach (string propertyName in propertyChain) {
    if (propertyName == "") {
        break;
    }

    PropertyInfo prop = currentObject.GetType().GetProperty(propertyName);
    currentObject = prop.GetValue(currentObject);
    if (currentObject == null) {
        // somehow handle the situation that one of the properties is null
    }
}

更新:props空の場合でもこれが機能することを保証するためのセーフガードを追加しました。その場合、currentObjectは元のMyClassインスタンスへの参照のままになります。

于 2012-08-27T11:41:16.363 に答える
1

ここで質問の答えを指しているので、同じことを達成するためにReglectionを利用する必要があります。

リフレクションの助けを借りて、あなたは財産の価値を読むことができます。

このようなもの、

// dynamically load assembly from file Test.dll
Assembly testAssembly = Assembly.LoadFile(@"c:\Test.dll");
// get type of class Calculator from just loaded assembly
Type calcType = testAssembly.GetType("Test.Calculator");
// create instance of class Calculator
object calcInstance = Activator.CreateInstance(calcType);
// get info about property: public double Number
PropertyInfo numberPropertyInfo = calcType.GetProperty("Number");
// get value of property: public double Number
double value = (double)numberPropertyInfo.GetValue(calcInstance, null);

あなたはあなたの要件に従って文字列を分割するよりも1つの関数にコードを入れる必要があります

public object getvalue(string propname)
{
  //above code with return type object 
}
String[] array = string.Split("foo.bar.value");
//call above method to get value of property..

詳細を読む:http ://www.csharp-examples.net/reflection-examples/

于 2012-08-27T11:36:59.520 に答える
1

FOOが静的であると仮定すると、次のような文字列からクラスを取得できます。

C#リフレクション:文字列からクラス参照を取得する方法は?

...次に、リンクした残りの投稿を使用して、そこからプロパティと値を取得します。

文字列名でプロパティ値を取得します

FOOが静的でない場合は、インスタンスでリフレクションを使用する必要があります(GetType()を使用してインスタンスからクラスを取得できるため、クラスの名前を文字列として渡す必要がなくなります)-静的でない限り、Barはクラスに値を持たないことを覚えておいてください。

于 2012-08-27T11:38:29.553 に答える