我问了一个关于Currying和关闭的问题.什么是关闭?它与currying有什么关系?
computer-science glossary functional-programming terminology
我最近在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
Run Code Online (Sandbox Code Playgroud)
intellisense文档AddDays()说它增加了一天的日期,它没有 - 它实际上返回添加了一天的日期,所以你必须写如下:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
Run Code Online (Sandbox Code Playgroud)
这个曾经多次咬过我,所以我认为编制最糟糕的C#陷阱会很有用.
我遇到了一个关于C#的有趣问题.我有如下代码.
List<Func<int>> actions = new List<Func<int>>();
int variable = 0;
while (variable < 5)
{
actions.Add(() => variable * 2);
++ variable;
}
foreach (var act in actions)
{
Console.WriteLine(act.Invoke());
}
Run Code Online (Sandbox Code Playgroud)
我希望它输出0,2,4,6,8.但是,它实际输出5个10.
似乎是由于所有操作都涉及一个捕获的变量.结果,当它们被调用时,它们都具有相同的输出.
有没有办法解决这个限制,让每个动作实例都有自己的捕获变量?
显然有很多方法可以迭代集合.好奇,如果有任何差异,或为什么你使用一种方式而不是另一种方式.
第一种:
List<string> someList = <some way to init>
foreach(string s in someList) {
<process the string>
}
Run Code Online (Sandbox Code Playgroud)
另一种方式:
List<string> someList = <some way to init>
someList.ForEach(delegate(string s) {
<process the string>
});
Run Code Online (Sandbox Code Playgroud)
我认为,除了我上面使用的匿名代表之外,我还有一个你可以指定的可重用代理......
让我们假设我们有一个结构,用于保存3个带有一些成员函数的双精度数:
struct Vector {
double x, y, z;
// ...
Vector &negate() {
x = -x; y = -y; z = -z;
return *this;
}
Vector &normalize() {
double s = 1./sqrt(x*x+y*y+z*z);
x *= s; y *= s; z *= s;
return *this;
}
// ...
};
Run Code Online (Sandbox Code Playgroud)
这有点简单,但我相信你同意类似的代码.这些方法可以方便地链接,例如:
Vector v = ...;
v.normalize().negate();
Run Code Online (Sandbox Code Playgroud)
甚至:
Vector v = Vector{1., 2., 3.}.normalize().negate();
Run Code Online (Sandbox Code Playgroud)
现在,如果我们提供了begin()和end()函数,我们可以在new-style for循环中使用Vector,比如循环遍历3个坐标x,y和z(你无疑可以构造更多"有用"的例子通过用例如String替换Vector):
Vector v = ...;
for (double x : v) { ... }
Run Code Online (Sandbox Code Playgroud)
我们甚至可以这样做:
Vector v = ...;
for …Run Code Online (Sandbox Code Playgroud) 我收到以下警告:
在关闭时访问foreach变量.使用不同版本的编译器编译时可能会有不同的行为.
这就是我的编辑器中的样子:

我知道怎么修这个警告,但我想知道为什么我会收到这个警告?
这是关于"CLR"版本的吗?它与"IL"有关吗?
这在C#5.0中正常工作(按预期方式):
var actions = new List<Action>();
foreach (var i in Enumerable.Range(0, 10))
{
actions.Add(() => Console.WriteLine(i));
}
foreach (var act in actions) act();
Run Code Online (Sandbox Code Playgroud)
打印0到9.但是这个显示10次10次:
var actions = new List<Action>();
for (var i = 0; i < 10; i++)
{
actions.Add(() => Console.WriteLine(i));
}
foreach (var act in actions) act();
Run Code Online (Sandbox Code Playgroud)
问题:这是我们在5.0之前的C#版本中遇到的问题; 所以我们不得不使用一个循环局部占位符来进行闭包,它现在已经修复了 - 在C#5.0中 - 在"foreach"循环中.但不是"for"循环!
这背后的原因是什么(也没有解决for循环问题)?
以下是:
MyObject myVariable;
for(int i = 0; i < objects.Length, i++){
myVariable = objects[i];
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
效率更高:
for(int i = 0; i < objects.Length, i++){
MyObject myVariable = objects[i];
// do stuff...
}
Run Code Online (Sandbox Code Playgroud)
因为每次都不会创建一个用于保存引用的新变量?(或者编译器足够智能,只是为了使用相同的变量)..
(如果创建了一个新变量,它是否在堆上进行了malloced?)
在以下示例中:
哪种编码更好?
第一个例子:
using System;
using System.Collections.Generic;
namespace TestForeach23434
{
class Program
{
static void Main(string[] args)
{
List<string> names = new List<string> { "one", "two", "two", "three", "four", "four" };
string test1 = "";
string test2 = "";
string test3 = "";
foreach (var name in names)
{
test1 = name + "1";
test2 = name + "2";
test3 = name + "3";
Console.WriteLine("{0}, {1}, {2}", test1, test2, test3);
}
Console.ReadLine();
}
} …Run Code Online (Sandbox Code Playgroud) 在.NET中了解有关标准事件模型的更多信息时,我发现在引入C#中的泛型之前,处理事件的方法由此委托类型表示:
//
// Summary:
// Represents the method that will handle an event that has no event data.
//
// Parameters:
// sender:
// The source of the event.
//
// e:
// An object that contains no event data.
public delegate void EventHandler(object sender, EventArgs e);
Run Code Online (Sandbox Code Playgroud)
但是在C#2中引入泛型之后,我认为这个委托类型是使用泛型重写的:
//
// Summary:
// Represents the method that will handle an event when the event provides data.
//
// Parameters:
// sender:
// The source of the event.
//
// e:
// …Run Code Online (Sandbox Code Playgroud)