简体   繁体   English

仅知道对象的名称,更新对象的属性

[英]Update a property on an object knowing only its name

I have some public variables that are defined as follows: 我有一些公共变量,定义如下:

public class FieldsToMonitor
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int Rev {get; set;}
}

I now want to populate those variable with values, but the fm.[varible name] needs be same as field.Name . 我现在想用值填充这些变量,但是fm.[varible name]需要与field.Name相同。 Here how I would populate in loop if I knew the property name ahead of time and the order of the property name: 如果我提前知道属性名称和属性名称的顺序,我将在这里填充循环:

// loop 1
fm.Id = revision.Fields[field.Name].Value;

// ... loop 2 ...
fm.Title = revision.Fields[field.Name].Value;

// ... loop 3 ...
fm.Rev = revision.Fields[field.Name].Value;

Here is what I would like to do where field.Name can be substituted with property name: 这是我想要做的事情,其中field.Name可以用属性名称替换:

  • fm.ID becomes fm.[field.Name] where field.Name == "ID" fm.ID变为fm。[field.Name]其中field.Name ==“ID”

  • fm.Title becomes fm.[field.Name] where field.Name == "Title" fm.Title变为fm。[field.Name]其中field.Name ==“Title”

  • fm.Rev becomes fm.[field.Name] and where field.Name == "Rev" fm.Rev变为fm。[field.Name],其中field.Name ==“Rev”

Is there a solution for this? 这有解决方案吗?

Here is more code of what I have so far: 这是我到目前为止的更多代码:

public class FieldsToMonitor
{
    public int Id { get; set; }
    public string Title { get; set; }
    public int Rev {get; set;}
}

static BindingList<FieldsToMonitor> FieldsToMonitorList
     = new BindingList<FieldsToMonitor>();
// ...

// Loop through the work item revisions
foreach (Revision revision in wi.Revisions)
{
    fm = new FieldsToMonitor();
    // Get values for the work item fields for each revision
    var row = dataTable.NewRow();
    foreach (Field field in wi.Fields)
    {
        fieldNameType = field.Name;
        switch (fieldNameType)
        {
            case "ID":
            case "Title":
            case "Rev":
                // the following doesn't work
                fm + ".[field.Name]" = revision.Fields[field.Name].Value; 
                fm[field.Name] = revision.Fields[field.Name].Value;
                row[field.Name] = revision.Fields[field.Name].Value;
                break;
        }
    }
}

This is all heavily dependent on how these values are being retrieved, and it is difficult to tell from your limited example if the values are strings or the correct type just boxed as an object. 这很大程度上取决于如何检索这些值,并且很难从有限的示例中判断出值是字符串还是仅作为对象加入的正确类型。

That being said, the following could work (but is hardly efficient): 话虽如此,以下可能会起作用(但效率不高):

public static void SetValue<T>(T obj, string propertyName, object value)
{
    // these should be cached if possible
    Type type = typeof(T);
    PropertyInfo pi = type.GetProperty(propertyName);

    pi.SetValue(obj, Convert.ChangeType(value, pi.PropertyType), null);
}

Used like: 使用如下:

SetValue(fm, field.Name, revision.Fields[field.Name].Value);
// or SetValue<FieldsToMonitor>(fm, ...);

I am not sure I understand you correctly but here is a try 我不确定我是否正确理解你,但这是一个尝试

public static class MyExtensions
{
    public static void SetProperty(this object obj, string propName, object value)
    {
        obj.GetType().GetProperty(propName).SetValue(obj, value, null);
    }
}

Usage like 用法就好

Form f = new Form();
f.SetProperty("Text", "Form222");

You're going to have to use reflection to accomplish that. 你将不得不使用反射来实现这一目标。 Here's a short example: 这是一个简短的例子:

class Foo
{
    public int Num { get; set; }
}

static void Main(string[] args)
{
    Foo foo = new Foo() { Num = 7 };

    Console.WriteLine(typeof(Foo).GetProperty("Num").GetValue(foo, null));
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM