我想做的是:

GetString(
    inputString,
    ref Client.WorkPhone)

private void GetString(string inValue, ref string outValue)
{
    if (!string.IsNullOrEmpty(inValue))
    {
        outValue = inValue;
    }
}

这给了我一个编译错误。我想我想达到的目的已经很清楚了。基本上我想要GetString复制输入字符串的内容到客户端的WorkPhone属性。

是否可以通过引用传递属性?


当前回答

为了对这个问题进行投票,这里有一个关于如何将其添加到语言中的积极建议。我并不是说这是最好的方法,请随意提出你自己的建议。但是允许像Visual Basic那样通过ref传递属性将极大地帮助简化一些代码,而且经常如此!

https://github.com/dotnet/csharplang/issues/1235

其他回答

这是不可能的。你可以说

Client.WorkPhone = GetString(inputString, Client.WorkPhone);

其中WorkPhone是一个可写的字符串属性和GetString的定义被更改为

private string GetString(string input, string current) { 
    if (!string.IsNullOrEmpty(input)) {
        return input;
    }
    return current;
}

这将具有与您所尝试的相同的语义。

这是不可能的,因为属性实际上是一对伪装的方法。每个属性都提供了可通过类字段语法访问的getter和setter。当您尝试调用GetString时,您传递的是一个值而不是一个变量。您传入的值是从getter get_WorkPhone返回的。

只是对内森的Linq表达式解决方案的一点扩展。使用多泛型参数,使属性不限于字符串。

void GetString<TClass, TProperty>(string input, TClass outObj, Expression<Func<TClass, TProperty>> outExpr)
{
    if (!string.IsNullOrEmpty(input))
    {
        var expr = (MemberExpression) outExpr.Body;
        var prop = (PropertyInfo) expr.Member;
        if (!prop.GetValue(outObj).Equals(input))
        {
            prop.SetValue(outObj, input, null);
        }
    }
}

这在c#语言规范的7.4.1节中介绍。只有变量引用可以作为参数列表中的ref或out形参传递。属性不符合变量引用的条件,因此不能使用。

是的,你不能传递一个属性,但你可以将你的属性转换为带有支持字段的属性,并做类似的事情。

public class SomeClass 
{
  private List<int> _myList;
  public List<int> MyList
  { 
    get => return _myList;
    set => _myList = value;
  }
  public ref List<int> GetMyListByRef()
  {
    return ref _myList;
  }
}

但有更好的解决方案,比如动作委托等。

属性不能通过引用传递?然后将其设置为字段,并使用该属性公开引用它:

public class MyClass
{
    public class MyStuff
    {
        string foo { get; set; }
    }

    private ObservableCollection<MyStuff> _collection;

    public ObservableCollection<MyStuff> Items { get { return _collection; } }

    public MyClass()
    {
        _collection = new ObservableCollection<MyStuff>();
        this.LoadMyCollectionByRef<MyStuff>(ref _collection);
    }

    public void LoadMyCollectionByRef<T>(ref ObservableCollection<T> objects_collection)
    {
        // Load refered collection
    }
}