C#通过引用传递属性

ctr*_*yan 23 .net c# properties pass-by-reference

无论如何通过引用传递Object的属性?我知道我可以传递整个对象,但是我想指定要设置的对象的属性并检查它的类型,以便我知道如何解析.我应该采取另一种方法(无论如何我都无法改变原始物体)?

public class Foo{
    public Foo(){}
    public int Age { get; set; }
}

private void setFromQueryString(object aProperty, String queryString, HttpContext context)
{
    //here I want to handle pulling the values out of 
    //the query string and parsing them or setting them
    //to null or empty string...
    String valueString = context.Request.QueryString[queryString].ToString(); 

    //I need to check the type of the property that I am setting.

    //this is null so I can't check it's type
    Type t = aProperty.GetType();
}

private void callingMethod(HttpContext context)
{
    Foo myFoo = new Foo();
    setFromQueryString(myFoo.Age, "inputAge", context);
}
Run Code Online (Sandbox Code Playgroud)

SLa*_*aks 18

您可以使用lambda表达式调用该函数:

private void setFromQueryString<T>(Action<T> setter, String queryString, HttpContext context) 
{ 
    //here I want to handle pulling the values out of  
    //the query string and parsing them or setting them 
    //to null or empty string... 
    String valueString = context.Request.QueryString[queryString].ToString();  

    //I need to check the type of the property that I am setting. 

    //this is null so I can't check it's type 
    Type t = typeof(T); 
    ...
    setter(value);
} 
Run Code Online (Sandbox Code Playgroud)

你会这样称呼它:

setFromQueryString<int>(i => myFoo.Age = i, "inputAge", context);
Run Code Online (Sandbox Code Playgroud)

编辑:如果你真的想要类型推断:

private void setFromQueryString<T>(Func<T> getter, Action<T> setter, String queryString, HttpContext context) {
    ...
}
setFromQueryString(() => myFoo.Age, i => myFoo.Age = i, "inputAge", context);
Run Code Online (Sandbox Code Playgroud)


Jef*_*tes 6

正如其他人所指出的那样,您可以使用委托来执行此操作,使用多种方法之一来指定委托.但是,如果您打算定期执行此操作,则应考虑创建一个包装类型,以便通过引用传递属性来包装所需的委托,它可以创建更好的API.

例如:

class PropertyReference<T>
{
   public T Value
   {
       get
       {
           return this.getter();
       }

       set
       {
           this.setter(value);
       }
   }

   public PropertyReference(Func<T> getter, Action<T> setter)
   {
      this.getter = getter;
      this.setter = setter;
   }
}
Run Code Online (Sandbox Code Playgroud)

这样,您可以传递对属性的引用,并通过设置引用值来修改它.

var reference = new PropertyReference(
                        () => this.MyValue,
                        x => this.MyValue = x);

reference.Value = someNewValue;
Run Code Online (Sandbox Code Playgroud)


Zac*_*son 5

您可以使用相应的方法和委托包装属性并传递委托.

delegate int IntGetter<T>(T obj);
delegate void IntSetter<T>(T obj, int value);

int GetAge(Foo foo)
{
    return foo.Age;
}

void SetAge(Foo foo, int value)
{
    foo.Age = value;
}

private void callingMethod(HttpContext context)
{
    Foo myFoo = new Foo();
    // need to also pass foo so the property can be set
    setFromQueryString(new IntSetter<Foo>(SetAge), foo, "inputAge", context);
}

private void setFromQueryString<T>(
    IntSetter<T> intSetter, 
    T obj, 
    String queryString, 
    HttpContext context)
{
    String valueString = context.Request.QueryString[queryString].ToString(); 
    intSetter(T, valueString);
}
Run Code Online (Sandbox Code Playgroud)


cas*_*One 5

不,没有办法通过引用直接传递属性.Visual Basic通过将属性的值放入临时变量,然后通过引用传递并在返回时重新分配,在语言中提供此支持.

在C#中,您只能通过传递a Func<T>来获取属性值来近似此行为,并且Action<T>用于设置值(使用闭包),其中T是属性的类型.