简体   繁体   English

将对象属性的引用传递给方法

[英]Pass a reference of an object's property to a method

I'm trying to learn how to pass some type of an argument that will tell a method which property it should edit.我正在尝试学习如何传递某种类型的参数,该参数将告诉方法它应该编辑哪个属性。

I'm trying to save an object with two string lists to a json file.我正在尝试将一个带有两个字符串列表的对象保存到一个 json 文件中。 So I have an "Add" method that adds a string to one of the lists, and that's where I need a parameter that determines/points/refers to which list I want the method to add to.所以我有一个“添加”方法,可以将一个字符串添加到其中一个列表中,这就是我需要一个参数来确定/指向/引用我希望该方法添加到哪个列表的地方。

I've tried to use Enums but then I'll have to use a lot of if statements in the method and I feel like there should be a better way to do it.我尝试使用 Enums,但随后我将不得不在方法中使用大量 if 语句,我觉得应该有更好的方法来做到这一点。

I've tried the ref keyword but then I have to create the object (before calling the "Add" method) and pass it to the method, but I don't want that, I want the method to create an object on it's own and know which list it must edit.我已经尝试了 ref 关键字,但后来我必须创建对象(在调用“Add”方法之前)并将其传递给方法,但我不想要那样,我希望方法自己创建一个对象并知道它必须编辑哪个列表。

NOTE: the following code has generic names and doesn't use lists and the whole json stuff for the sake of simplicity and clarity注意:为了简单和清晰起见,以下代码具有通用名称并且不使用列表和整个 json 内容

NOTE: the next code is taken from a console app注意:下一个代码取自控制台应用程序

NOTE: the "ChangeStuff" method's parameter (refProp) isn't right because I don't know what else to put there.注意:“ChangeStuff”方法的参数 (refProp) 不正确,因为我不知道还有什么可以放在那里。

So I want the method to work something like this:所以我希望该方法能够像这样工作:

class Stuff
    {
        public string One = "Normal";
        public string Two = "Normal";
    }

class Program
    {
        static void Main(string[] args)
        {
            var StuffObject = new Stuff();
            ChangeStuff(StuffObject.One);
        }

        static void ChangeStuff(refProp)
        {
            Stuff StuffObject = new Stuff();
            StuffObject.refProp = "Changed";
            Console.WriteLine(StuffObject.refProp);
        }
    }

I expect ChangeStuff to make an object and change the property that "refProp" points to and then writes that property's value to the console.我希望 ChangeStuff 创建一个对象并更改“refProp”指向的属性,然后将该属性的值写入控制台。

You could make use of Expressions for referring properties in your class in order to change them.您可以使用表达式来引用类中的属性以更改它们。 For example,例如,

static void Main(string[] args)
{
    var stuffObject = new Stuff();
    var result = ChangeStuff(stuffObject,x=>x.Two);
}

static T ChangeStuff<T>(T target,Expression<Func<T,object>> exp)
{
     var memberSelectorExpression = exp.Body as MemberExpression;
     if (memberSelectorExpression != null)
     {
        var property = memberSelectorExpression.Member as PropertyInfo;

        if (property != null)
        {
          property.SetValue(target, "Changed", null);
        }
      }
      return target;
}

Please note, you need to make your One and Two in the Class Stuff as Properties.请注意,您需要将 Class Stuff 中的 One 和 Two 设为 Properties。

class Stuff
{
        public string One {get;set;} ="Normal";
        public string Two {get;set;} ="Normal";
}

You could extend it further by passing the "New Value" as parameter.您可以通过将“新值”作为参数传递来进一步扩展它。

static TSource ChangeStuff<TSource,TValue>(TSource target,Expression<Func<TSource,TValue>> exp,TValue newValue)
{
    var memberSelectorExpression = exp.Body as MemberExpression;
    if (memberSelectorExpression != null)
    {
        var property = memberSelectorExpression.Member as PropertyInfo;
        if (property != null)
        {
            property.SetValue(target, newValue, null);
        }
    }
    return target;
}

Now you could call the method as现在您可以将该方法称为

ChangeStuff(stuffObject,x=>x.Two,"This is new value");

There may be a different way to approach the problem that would avoid having to do this.可能有一种不同的方法来解决这个问题,而不必这样做。 But if your do have to, you can pass a PropertyInfo:但是,如果您必须这样做,您可以传递一个 PropertyInfo:

ChangeStuff( stuff.GetType().GetProperty( nameof(stuff.One))

Then in the method use Set Value on the property然后在该方法中对属性使用 Set Value

public void ChangeStuff( PropertyInfo property)
{
     var stuff = new Stuff();
     property.SetValue( stuff, "revised value", null);
}

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

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