我有一个包含字符串属性的类(比如classA
)。
我想将它设置为另一个类的字符串属性(比如classB
),这样当我将属性更改为classA
时,它会在classB
中更改,反之亦然。
我知道我可以通过ref
使用函数执行此操作但是当我在我的类(构造函数)上尝试它时它不起作用
这就是我所拥有的;
public class myClass
{
public string Name;
public int Image;
public myClass(ref string myName)
{
Name = myName;
}
public void changeIt()
{
Name = "xyz";
}
}
我的主要代码;
string myString = "abc";
Console.WriteLine("myString:"+myString);
myClass mClass = new myClass(ref myString);
mClass.changeIt();
Console.WriteLine("myString (After doThis):" + myString);
Console.ReadLine();
当我运行它时会生成;
myString:abc
myString (After doThis):abc
我在这里缺少什么?为什么不改为xyz
?
答案 0 :(得分:4)
字符串是不可变的。这意味着,当你改变"一根绳子......你实际上扔掉旧的并创造了一个全新的。如果不使用一些狡猾的不安全代码,就无法解决这个问题。 ("扔掉"在这种情况下......忘了它......允许垃圾收集器稍后清理它。)
在代码的上下文中,这意味着:
Name = "xyz";
使用内容xyz
创建新的字符串引用,并将其分配给引用Name
。调用者中的myString
不受此影响..它是一个不同的引用。
答案 1 :(得分:2)
如@SimonWhitehead所述,字符串是不可变的。在这种情况下,您可以做的是更改changeIt
方法以获取out
参数,然后传入myString
作为输入,如下所示:
public void changeIt(out string myName)
{
myName = "xyz";
}
这将为您提供输出" xyz"在您调用此方法之后:
myClass.changeIt(out myString);
答案 2 :(得分:2)
一般来说,对象状态的变化应该与事件进行通信。
所以在班级中有重要的"属性,当你改变它的值时,应该触发一个事件。
其他类应该被吸引到这个事件并抓住它。
您可以将已更改字符串的值添加到已触发事件中,这样您甚至无需在字符串值更改时引用该对象。
您可以在this link上查看事件在C#中的工作原理。
如何操作的示例如下:
class ClassWithImportantProperty
{
string myString = string.Empty;
public string MyImportantProperty
{
get { return myString; }
set
{
myString = value;
if (PropertyChanged != null)
PropertyChanged(myString, EventArgs.Empty);
}
}
public event EventHandler PropertyChanged;
}
class SecondClass
{
public string MyDependantString { get; set; }
public secondClass()
{
var classInstance = new ClassWithImportantProperty();
classInstance.PropertyChanged += classInstance_PropertyChanged;
}
void classInstance_PropertyChanged(object sender, EventArgs e)
{
MyDependantString = sender.ToString();
}
}
基本上,每当其中一个属性发生变化时,您就会有一个类触发事件。 然后是另一个被这个事件引起的类,每次被触发时,都会执行它自己的一些过程。
答案 3 :(得分:1)
您正在将一个字符串引用到构造函数中并在其他方法中更改其值。因此,ref
关键字仅适用于代码块,在这种情况下是构造函数。
此代码会将值myName更改为Name。但是在调用构造函数之后,myName将不再引用Name。请注意,您要将名称指定给ref myName,它不会引用名称。
public myClass(ref string myName)
{
myName = Name;
}
这也将改变字符串:
public void changeIt(ref string myName)
{
Name = "xyz";
myName = Name;
}
我不会写不可变因为其他人已经回答了。你可以使用这样的接口来实现这个技巧:
class Program
{
public interface IName
{
string Name { get; }
}
public class myClass : IName
{
public string Name { get; set; }
public myClass(string myName)
{
Name = myName;
}
public void changeIt()
{
Name = "xyz";
}
}
public class myClass2 : IName
{
private IName iname;
public string Name { get { return iname.Name; } }
public myClass2(IName myName)
{
iname = myName;
}
}
static void Main(string[] args)
{
myClass mClass = new myClass("abc");
myClass2 m2Class = new myClass2(mClass);
Console.WriteLine("myString:" + m2Class.Name);
mClass.changeIt();
Console.WriteLine("myString (After doThis):" + m2Class.Name);
Console.ReadLine();
}
}
它实际上会做你想要达到的目标。
答案 4 :(得分:0)
要更改string
,请在代码中进行以下更改。
public string changeIt()
{
return "xyz"; //return a string from method
}
在通话部分
myString=mClass.changeIt(); //assign return value to myString