【问题标题】:How to set value of a property that is a class in C#如何在 C# 中设置作为类的属性的值
【发布时间】:2015-12-08 11:16:30
【问题描述】:

我正在尝试设置作为类的属性的值。

protected bool TryUpdate(PropertyInfo prop, object value)
{
    try
    {
        prop.SetValue(this, value);

        // If not set probably a complex type
        if (value != prop.GetValue(this))
        {
           //... Don't know what to do
        }
        // If still not set update failed
        if (value != prop.GetValue(this))
        {
            return false;
        }
        return true;

    }

}

我正在对来自各种类的许多属性调用此方法。这个问题是当我有一个像下面这样的类时:

public class Test
{
    public string Name { get; set; }

    public string Number { get; set; }

    public IComplexObject Object { get; set; }
}

Name 和 Number 设置得很好,但是如果我尝试设置从 IComplexObject 继承的类的实例 Object 没有错误,它只是保持为空。

有没有一种简单的方法可以将类的实例设置为属性?

例如,如果我将 prop 作为 {IComplexObject Object} 和 object 作为

var object = (object) new ComplexObject
{
    prop1 = "Property"
    prop2 = "OtherProperty"
}

最后没有错误,但 Object 仍然为 null 并且未设置为 ComplexObject 的实例。它需要是通用的,所以我可以传入任何类并且属性将被更新。

【问题讨论】:

  • 假设示例在设置Object属性时没有产生任何异常,那么设置应该是成功的。也许您的IComplexObjects 的平等比较是什么行为不端?逐步调试在这里会很有帮助。如果是相等,那么您可以尝试将比较替换为 ReferenceEquals 对于初学者
  • 为什么你的更新方法是异步的?它似乎没有使用任务。
  • 发布一个简短但完整、可重现的代码...
  • 更新了代码和问题,使其更加清晰。我的问题是 SetValue 没有设置 Object 它只是保持 null 没有任何异常。

标签: c# reflection properties set


【解决方案1】:

您的代码不必要地复杂,但它完全可以正常工作。我已经获取了您的代码并将其扩展为可以运行的完整示例。

输出是这样的。

Name: asdf, Number: A1B2, Object: hello this is complexobject
It was not null

这表明Object 属性与其他属性没有什么不同。 “复杂对象”在.net 中并不是一个真正意味着任何东西的术语。此外,您对async 的使用似乎没有必要且令人困惑。

async void Main() {
    Test t = new Test();
    Type type = typeof(Test);

    await t.TryUpdate(type.GetProperty(nameof(t.Name)), "asdf");
    await t.TryUpdate(type.GetProperty(nameof(t.Number)), "A1B2");
    await t.TryUpdate(type.GetProperty(nameof(t.Object)), (object)new ComplexObject());

    Console.WriteLine(t.ToString());

    PropertyInfo prop = type.GetProperty(nameof(t.Object));

    if (prop.GetValue(t) == null) {
        Console.WriteLine("It was null");
    } else {
        Console.WriteLine("It was not null");
    }
}

public class Test {
    public string Name { get; set; }
    public string Number { get; set; }
    public IComplexObject Object { get; set; }

    // Added for the purpose if showing contents
    public override string ToString() => $"Name: {Name}, Number: {Number}, Object: {Object}";

    // Why is this async?  Your code does not await
    public async Task<bool> TryUpdate(PropertyInfo prop, object value) {
        await Task.Delay(0); // Added to satisfy async
        try {
            prop.SetValue(this, value);

            // If not set probably a complex type
            if (value != prop.GetValue(this)) {
                //... Don't know what to do
            }

            return true;
        }
        catch {
            return false;
        }
    }

}

public interface IComplexObject { }
class ComplexObject : IComplexObject {
    public override string ToString() => "hello this is complexobject";
}

【讨论】:

  • 更新了代码和问题,使其更加清晰。我的问题是 SetValue 没有设置 Object 它只是保持为空,没有任何例外。我正在寻找的是在 if 语句中放入什么来设置 Object,因为 set Value 不起作用。
  • 你的问题还不清楚。我示例中的代码显示设置Object 确实 有效。属性设置为ComplexObject的实例,不再为空。
  • 然后我很困惑这对我不起作用。如果是: if (prop.GetValue(this) == null) { return false } 这意味着该值未设置我的返回 false。
  • 我在示例中添加了一些代码来执行if (prop.GetValue(this) == null),它正确地显示了该值已设置并且不再为空。该代码有效,我无法根据您的代码重现该问题。事实上,我示例中的代码显示了相反的情况。请包含足够的代码来重现问题。
【解决方案2】:

这个例子有效。我已经把它作为参考。
我已将其更改为等待任务并将返回值提取到结果变量中,以便您可以看到它返回 true。

public class Test
{
    public string Name { get; set; }

    public string Number { get; set; }

    public IComplexObject Object { get; set; }

    public async Task<bool> TryUpdate(PropertyInfo prop, object value) {
        try {
            prop.SetValue(this, value);
            return true;
        }
        catch (Exception) {

        }

        return false;
    }

}

public class ComplexObject : IComplexObject
{
}

public interface IComplexObject
{

}
static class  Program
{

    static void Main() {
        TestMethod();
    }

    static async void TestMethod() {
        var test = new Test();
        var result = await test.TryUpdate(test.GetType().GetProperty("Object"), new ComplexObject());
    }
}

【讨论】:

  • 您的代码对我来说返回 Object 为 null。我的代码返回 false 没有任何错误。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-11
  • 1970-01-01
  • 1970-01-01
  • 2012-02-09
  • 1970-01-01
相关资源
最近更新 更多