我想做的是:

GetString(
    inputString,
    ref Client.WorkPhone)

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

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

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


当前回答

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

其他回答

您可以尝试做的是创建一个对象来保存属性值。这样,您可以传递对象,但仍然可以访问内部的属性。

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

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
    }
}

看起来,您需要对该字段施加业务规则约束,同时又希望使您的代码尽可能地保持DRY。

它是可以实现的,也可以通过在字段上实现一个完整的属性并使用您的可重用方法来保存您的域语义:

public class Client
{
    private string workPhone;

    public string WorkPhone
    {
        get => workPhone;
        set => SafeSetString(ref workPhone, value);
    }

    private void SafeSetString(ref string target, string source)
    {
        if (!string.IsNullOrEmpty(source))
        {
            target = source;
        }
    }
}

SafeSetString方法可以放在Utilities类中或任何有意义的地方。

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

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;
  }
}

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

没有复制属性

void Main()
{
    var client = new Client();
    NullSafeSet("test", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet("", s => client.Name = s);
    Debug.Assert(person.Name == "test");

    NullSafeSet(null, s => client.Name = s);
    Debug.Assert(person.Name == "test");
}

void NullSafeSet(string value, Action<string> setter)
{
    if (!string.IsNullOrEmpty(value))
    {
        setter(value);
    }
}