4

これが私が意味することです:

この見苦しい C# コードを代用できるようにする必要があります。

if (attribute.Name == "Name") machinePool.Name = attribute.Value;
else if (attribute.Name == "Capabilities") machinePool.Capabilities = attribute.Value;
else if (attribute.Name == "FillFactor") machinePool.FillFactor = attribute.Value;

このようなものに:

machinePool.ConvertStringToObjectField(attribute.Name) = attribute.Value;

ConvertStringToObjectField() メソッドはありませんが、可能であればこのようなものが欲しいです。machinePool オブジェクト クラス コードにアクセスできるので、必要なコードを追加できますが、それがどのようなコードなのか、または C# で実行できるのかさえわかりません。

4

3 に答える 3

9

はい、リフレクションを通じてこれを行うことができます。

var fieldInfo = machinePool.GetType().GetField(attribute.Name);
fieldInfo.SetValue(machinePool, attribute.Value);

簡単にするために拡張メソッドを作成することもできます。

public static void SetField(this object o, string fieldName, object value)
{
    var fi = o.GetType().GetField(fieldName);
    fi.SetValue(o, value);
}
于 2009-10-30T00:50:53.303 に答える
0

はい、できます。プロパティ名を文字列として取得したい (つまり、PropertyChangedEventHandler を処理する) ときに使用するコードを次に示しますが、文字列自体は使用したくありません。

    public static string GetPropertyName<T>(Expression<Func<T, object>> propertyExpression)
    {
        Check.RequireNotNull<object>(propertyExpression, "propertyExpression");
        switch (propertyExpression.Body.NodeType)
        {
            case ExpressionType.MemberAccess:
                return (propertyExpression.Body as MemberExpression).Member.Name;
            case ExpressionType.Convert:
                return ((propertyExpression.Body as UnaryExpression).Operand as MemberExpression).Member.Name;
        }
        var msg = string.Format("Expression NodeType: '{0}' does not refer to a property and is therefore not supported", 
            propertyExpression.Body.NodeType);
        Check.Require(false, msg);
        throw new InvalidOperationException(msg);
    }

そして、これを処理するのに役立つテストコードを次に示します。

[TestFixture]
public class ExpressionsExTests
{
    class NumbNut
    {
        public const string Name = "blah";
        public static bool Surname { get { return false; } }
        public string Lame;
        public readonly List<object> SerendipityCollection = new List<object>();
        public static int Age { get { return 12; }}
        public static bool IsMammel { get { return _isMammal; } }
        private const bool _isMammal = true;
        internal static string BiteMe() { return "bitten"; }
    }

    [Test]
    public void NodeTypeIs_Convert_aka_UnaryExpression_Ok()
    {
        Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Age), Is.EqualTo("Age"));
        Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.IsMammel), Is.EqualTo("IsMammel"));
        Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Surname), Is.EqualTo("Surname"));
    }

    [Test]
    public void NodeTypeIs_MemberAccess_aka_MemberExpression_Ok()
    {
        Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => nn.SerendipityCollection), Is.EqualTo("SerendipityCollection"));
        Assert.That(ExpressionsEx.GetPropertyName<NumbNut>(nn => nn.Lame), Is.EqualTo("Lame"));
    }

    [Test]
    public void NodeTypeIs_Call_Error()
    {
        CommonAssertions.PreconditionCheck(() => ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.BiteMe()),
                                           "does not refer to a property and is therefore not supported");
    }

    [Test]
    public void NodeTypeIs_Constant_Error() {
        CommonAssertions.PreconditionCheck(() => ExpressionsEx.GetPropertyName<NumbNut>(nn => NumbNut.Name),
                                           "does not refer to a property and is therefore not supported");
    }

    [Test]
    public void IfExpressionIsNull_Error()
    {
        CommonAssertions.NotNullRequired(() => ExpressionsEx.GetPropertyName<NumbNut>(null));
    }

    [Test]
    public void WasPropertyChanged_IfPassedNameIsSameAsNameOfPassedExpressionMember_True()
    {
        Assert.That(ExpressionsEx.WasPropertyChanged<NumbNut>("SerendipityCollection", nn => nn.SerendipityCollection), Is.True);
    }

    [Test]
    public void WasPropertyChanged_IfPassedPropertyChangeArgNameIsSameAsNameOfPassedExpressionMember_True()
    {
        var args = new PropertyChangedEventArgs("SerendipityCollection");
        Assert.That(ExpressionsEx.WasPropertyChanged<NumbNut>(args, nn => nn.SerendipityCollection), Is.True);
    }

}

HTH

ベリル

于 2009-10-30T00:52:21.433 に答える
0

次のようなことができます:

void SetPropertyToValue(string propertyName, object value)
{
    Type type = this.GetType();
    type.GetProperty(propertyName).SetValue(this, value, null);
}

次に、次のように使用します。

machinePool.SetPropertyToValue(attribute.Name, attribute.Value);
于 2009-10-30T00:53:15.817 に答える