我有一个变量,我想在函数内部进行更改,并反映原始变量中的新变化。我试图在函数内部将原始变量值更改为Scott,然后在函数外反映出新的更改:
public ActionResult HomePage()
{
string name = "John";
ChangeName(name);
string newName = name ; -- This still says John
}
public static void ChangeName(string myname)
{
myname = "Scott";
}
答案 0 :(得分:6)
您可以通过引用 -
传递字符串来实现public ActionResult HomePage()
{
string name = "John";
ChangeName(ref name);
string newName = name ; -- This is now Scott.
}
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
但是,正如TheSoftwareJedi在评论中所述,通常最好避免通过引用传递参数。相反,你应该让你的方法返回新的字符串,特别是考虑到字符串是不可变的,所以你不能真正改变它们,你只能改变引用指向另一个字符串。
所以更好的方法是这样的:
public static string GetAnotherName()
{
return "Scott";
}
更深入一点 - 在c#中基本上有两种类型(至少与这一点相关):有值类型,如枚举,结构(包括所有基本类型,如int,bool等' )并且有参考类型(基本上,其他一切)。
无论何时将参数传递给方法,它都会按值传递,除非您指定ref
(或out
)关键字,即使它是引用类型(在这种情况下) ,引用按值传递)。这意味着当您为方法内的参数分配新值时,如果参数通过引用显式传递(使用ref
或out
关键字),您将只在方法外部看到它
引用类型和值类型之间的主要区别在于,当您在方法中更改引用类型的属性时,您将在方法外部看到新值,但是当您更改内部值类型的属性时一种方法,该变化不会反映到该方法之外的变量。
答案 1 :(得分:1)
首先,我建议您阅读有关引用,值和参数传递的信息。 Jon Skeet对此主题进行了很好的总结 - Parameter passing in C#以及Eric Lippert对参考概念的良好解释 - References are not addresses。
你应该知道默认情况下,参数是通过C#中的值传递的,这意味着参数将包含作为参数传递的引用的副本,这意味着赋值只会更改参数本身,并且在调用站点处不会被观察到。
这就是为什么
myname = "Scott";
仅更改方法参数myname
的值,而不更改外部name
变量。
同时,我们可以使用ref
,in
或out
关键字通过引用传递我们的变量。虽然in
和out
关键字正在添加超出主题的超额保证,但我将继续使用ref
。
您应该更改方法的声明并调用网站以使用它。
public static void ChangeName(ref string myname)
{
myname = "Scott";
}
它应该现在作为
调用ChangeName(ref name);
这次没有复制,因此myname
参数存储与name
变量相同的引用,而且参数和变量存储在一个位置,这意味着更改为myname
内部调用代码时可以看到ChangeName
方法。
要继续,我想就您的问题 - Expressions和Statements指出一个单独但相关的主题,并将您链接到一篇关于他们的好文章。 Scott Wlaschin - Expressions vs statements(里面有一些F#,但这并不重要)。
通常情况下,您选择的方法没有任何问题,但这是必要的,基于陈述的,有点太低级别。您被迫处理引用及其值,而您真正想要的只是从您的方法中获得值“Scott”。如果实现为表达式,这将看起来更直接和明显。
public static string GetName() => "Scott";
这种方式代码是声明性的,因此更简单(和简短),它直接说明了你的目标。