0

尝试更改类内的字符串属性时发生错误,但如果将('f.StartTime' 分配给字符串变量它可以工作但不会更改'StartTime' 属性)

喜欢:

string x = f.StartTime;
ChangeText(ref x);  // There's no error, but f.StartTime didn't change.
//Unless:
f.StartTime = x;

当然是假方法...

所以我想执行以下代码。

public class MainClass
{
    public class Foo
    {
        public string StartTime { get; set; }
        public string ToTime { get; set; }
    }

    private void ChangeText(ref string Time)
    {
        Time = DateTime.Now.ToString();
    }

    public void SetClassObjects()
    {
        Foo f = new Foo()
        {
            StartTime = "Any Text",
            ToTime = "Any Text"
        };

        ChangeText(ref f.StartTime);

        // An error: A property, indexer or dynamic member access may not be passed as an out or ref parameter
    }
4

1 回答 1

1

字符串是不可变的,分配f.StartTimex创建的是的副本而不是引用的副本。因此,您需要重新分配f.StartTime. 包含将ref正确地重新分配引用x(实际上指向 下的新字符串x),但由于字符串的值类型语义,引用f.StartTime丢失。请注意,字符串是引用类型,它们只是遵循值类型的语义。

在这种情况下,我会回避提供stringas a ref,而是执行以下操作:

f.StartTime = GetText();

private string GetText()
{
    return DateTime.Now.ToString();
}

或者传递FooChangeText方法:

private void ChangeText(Foo fooItem)
{
    fooItem.Time = DateTime.Now.ToString();
}

那么就ChangeText(f);.

如果你想提供一个通用机制来改变属性字符串,你可以有一个接口:

public interface ICanHaveMyTextChanged 
{
    void ChangeText(string newText);
}

哪个Foo实现:

class Foo : ICanHaveMyTextChanged 
{
    public string StartTime { get; private set; }

    public void ChangeText(string newText)
    {
        StartTime = newText;
    }
}

然后将接口指定为参数,而不是Foo

private void ChangeText(ICanHaveMyTextChanged item)
{
    item.ChangeText(DateTime.Now.ToString());
}

并这样称呼:

var f = new Foo();
ChangeText(f);

现在任何实现这个接口的类都可以改变它的文本。

于 2012-07-11T10:51:19.837 回答