我最近正在使用一个DateTime对象,并写了这样的东西:
DateTime dt = DateTime.Now;
dt.AddDays(1);
return dt; // still today's date! WTF?
AddDays()的智能感知文档说它在日期后添加了一天,但它并没有这样做——它实际上返回了一个添加了一天的日期,所以你必须这样写:
DateTime dt = DateTime.Now;
dt = dt.AddDays(1);
return dt; // tomorrow's date
这个问题以前已经困扰过我很多次了,所以我认为将最糟糕的c#陷阱分类会很有用。
不是最糟糕的,但还没被提起。工厂方法作为参数传递给System.Collections.Concurrent方法可以被多次调用,即使只使用了一个返回值。考虑到. net在线程原语中多么强烈地试图保护您不受虚假唤醒的影响,这可能会让您感到惊讶。
using System;
using System.Collections.Generic;
using System.Collections.Concurrent;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ValueFactoryBehavingBadlyExample
{
class Program
{
static ConcurrentDictionary<int, int> m_Dict = new ConcurrentDictionary<int, int>();
static ManualResetEventSlim m_MRES = new ManualResetEventSlim(false);
static void Main(string[] args)
{
for (int i = 0; i < 8; ++i)
{
Task.Factory.StartNew(ThreadGate, TaskCreationOptions.LongRunning);
}
Thread.Sleep(1000);
m_MRES.Set();
Thread.Sleep(1000);
Console.WriteLine("Dictionary Size: " + m_Dict.Count);
Console.Read();
}
static void ThreadGate()
{
m_MRES.Wait();
int value = m_Dict.GetOrAdd(0, ValueFactory);
}
static int ValueFactory(int key)
{
Thread.Sleep(1000);
Console.WriteLine("Value Factory Called");
return key;
}
}
}
(可能)输出:
Value Factory Called
Value Factory Called
Value Factory Called
Value Factory Called
Dictionary Size: 0
Value Factory Called
Value Factory Called
Value Factory Called
Value Factory Called
enum Seasons
{
Spring = 1, Summer = 2, Automn = 3, Winter = 4
}
public string HowYouFeelAbout(Seasons season)
{
switch (season)
{
case Seasons.Spring:
return "Nice.";
case Seasons.Summer:
return "Hot.";
case Seasons.Automn:
return "Cool.";
case Seasons.Winter:
return "Chilly.";
}
}
错误呢?
不是所有的代码路径都返回一个值…
你在开玩笑吗?我打赌所有代码路径都返回一个值,因为这里提到了每个Seasons成员。它应该已经检查所有enum成员,如果一个成员在开关情况下是缺席的,那么这样的错误将是有意义的,但现在我应该添加一个默认情况下,这是冗余的,永远不会被代码达到。
编辑:
在对这个Gotcha进行了更多的研究之后,我看到了Eric Lippert写得很好的和有用的帖子,但它仍然有点奇怪。你同意吗?
Foreach循环变量范围!
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
l.Add(() => s);
}
foreach (var a in l)
Console.WriteLine(a());
打印五个“amet”,而下面的例子可以正常工作
var l = new List<Func<string>>();
var strings = new[] { "Lorem" , "ipsum", "dolor", "sit", "amet" };
foreach (var s in strings)
{
var t = s;
l.Add(() => t);
}
foreach (var a in l)
Console.WriteLine(a());