我以为我明白了区别,但现在我不太确定。我已多次阅读技术答案,但我不明白发生了什么。我有这个例子。
class Program
{
static void Main()
{
int val = 0;
Example1(val);
Console.WriteLine(val); // Still 0!
Example2(ref val);
Console.WriteLine(val); // Now 2!
Example3(out val);
Console.WriteLine(val); // Now 3!
}
static void Example1(int value)
{
value = 1;
}
static void Example2(ref int value)
{
value = 2;
}
static void Example3(out int value)
{
value = 3;
}
}
我一直认为默认参数之间的区别在于,如果我将val传递给Example1,我就不能使用赋值。
但是ref关键字val仍然是0,但我创建了一个引用,现在被视为Example2(ref val)中的变量“value”。到目前为止,我是否被挂了?如果我用过
int value = 0;
Example1(value);
Console.WriteLine(value); // this would then return 1 correct?
现在,out关键字会发生什么?和ref一样吗?
答案 0 :(得分:0)
在第一个示例中,您没有指定变量是引用,并且因为它是基本类型,所以它只复制提供的数字。因此value
中的Example1
是value
中Main
的副本。
第二个示例使用引用。这意味着函数Example2
和内部Main
内部都指向内存中的相同位置,因此当进入和退出函数时,值都会被转移。
在第三个示例中,out
关键字与第二个关键字相同,只是在输入函数时初始化为0。因此,它只是返回某种数据的参数。退出函数时只传输该值。
答案 1 :(得分:0)
看看这是否有帮助:
否"装饰者"
static void Example(int value)
{
Console.WriteLine("Value is {0}", value);
value = 99;
}
usage
{
int value = 10;
Example(notADefaultValue); // Will print <Value is 10>
Console.WriteLine("Value is {0}", value); // will print <Value is 10>
}
总结:默认情况下,值类型(结构/枚举/ int / double / etc)不作为引用传入,因此无论您对方法中的变量执行什么操作都不会影响调用方。因此,&#34; ref&#34;关键词。如果将引用类型传递给方法(即类)并更改它的内部,则会影响调用者。
默认参数:
static void Example(int value = 5)
{
Console.WriteLine("Value is {0}", value);
}
usage
{
int notADefaultValue = 10;
Example(notADefaultValue); // Will print <Value is 10>
Example(); // will print <Value is 5>
}
摘要:默认值允许您在不明确需要传递参数的情况下调用方法,使用默认值。
参考参数:
static void Example(ref int value)
{
Console.WriteLine("Value is {0}", value);
value = 99;
}
usage
{
int value = 10;
Example(ref value); // Will print <Value is 10>
Console.WriteLine("Value is {0}", value); // Will print <Value is 99>
}
摘要:如果将值类型作为ref(引用)传递,则值本身会发生更改。默认情况下,所有引用类型都作为ref传入。 FYI,int是一种原始类型,因此需要一个明确的&#34; ref&#34;。
输出参数:
static void Example(out int value)
{
value = 99;
Console.WriteLine("Value is {0}", value);
}
usage
{
int value; // no need to init it
Example(out value); // Will print <Value is 99>
Console.WriteLine("Value is {0}", value); // Will print <Value is 99>
}
总结:Out参数类似于返回变量,但是通过方法的签名传入。最常见的示例是TryParse,其中该方法返回重要信息,并且根据该信息,out参数有效或无效(如果为真,则有效)。
答案 2 :(得分:0)
好的,它是评论中链接问题的副本,但我会尝试为您解释。
未修改的参数
案例A:public void MyFunc(int x) { }
- 或 -
案例B:public void MyFunc(MyClass y) { }
在案例A中,参数是值类型,默认情况下,值类型作为原始值的副本传递给函数。这并不意味着您不允许修改该值,但该值不会反映在调用位置。这对于所有值类型都是相同的,在传递给函数之前,值是复制。
在案例B中,参数是引用类型。默认情况下会按原样传递这些类型。它们不会被复制,但您不能更改引用(通过为类型指定new
或null
值)。您可以更改对象的内容(其中的任何属性/字段),将反映回调用位置。
ref关键字
案例A:public void MyFunc(ref int x) { }
-OR -
案例B:public void MyFunc(ref MyClass x) { }
在A的情况下,您告诉编译器您希望通过引用传递值,这意味着编译器不会复制该类型,而是传递对该类型的引用。该功能可以更改它。
在案例B中,您告诉编译器允许函数 更改引用指向的位置(您可以创建new
或将其设置为null
它将反映在呼叫站点中。
out关键字
案例A:public void MyFunc(out int x) { }
-OR -
案例B:public void MyFunc(out MyClass x) { }
在这里,您基本上是为函数定义其他返回类型。它的方法参数告诉调用者在x
变量的位置预期结果。两者都是一样的。在任何情况下,调用者都不应该期望之前x
之前的任何值都是相同的。实际上,您可以预期它将不相同,因为该方法需要在允许返回之前为x分配新值。
out
基本上意味着您为返回值提供了一个位置,对于值类型,只需使用默认构造函数,对于引用类型,在将值传递给null
之前将其初始化为 getAyahsByJuz: function (juzIndex) {
var response = [];
var promises = [];
var self = this;
var deferred = $q.defer();
$timeout(function () {
$http.get('data/quran.json').success(function (data) {
var ayahs = Quran.ayah.listFromJuz(juzIndex);
angular.forEach(ayahs, function (value, key) {
var promise = self.getVerse(value.surah, value.ayah).then(function (res) {
var verse = {
surah: value.surah,
ayah: value.ayah,
text: res
};
response.push(verse);
}, function (err) {
console.log(err);
});
promises.push(promise);
});
});
}, 30);
$q.all(promises).then(function() {
deferred.resolve(response);
});
return deferred.promise;
},
。