使用ref从外部方法更改类属性

时间:2012-07-11 10:46:54

标签: c#

尝试更改类内的字符串属性时发生错误, 但如果将(' 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
    }

1 个答案:

答案 0 :(得分:1)

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

在这个例子中,我会回避提供string作为ref,而是执行以下操作:

f.StartTime = GetText();

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

或者将Foo传递到ChangeText方法:

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

现在任何实现此接口的类都可以更改它的文本。

相关问题