我一直在玩C#6的Null Conditional Operator(这里有更多信息).
我非常喜欢语法,我认为它使代码更具可读性,但我认为当你遇到一个本身可能为null的对象上的属性值时,代码究竟要做什么是值得怀疑的.
例如,如果我有一个带有十进制属性的类,并且我想要对该十进制值进行条件检查,我会写如下:
if (foo?.Bar > max)
{
// do something
}
Run Code Online (Sandbox Code Playgroud)
从表面上看,这看起来很棒......如果foo不为null,则获取Bar的值并检查它是否大于最大值,如果是,则执行某些操作.
但是,如果foo为null会怎么样?!
如果实际上对象的值为null,则null条件运算符将返回null.它将对Bar的调用短路,并立即返回null,避免编程错误,否则会导致NullReferenceException.
我在这里写了一个小提琴,表明它确实起作用,正在做我期待它做的事情但是我无法理解它是如何决定条件的结果.
短路如何等于假?在我的脑海中,这段代码现在要说"如果foo为null,检查null是否> max,这是不可能的,所以返回false"或"如果foo为null,那么foo!= null将返回false,所以你得到一个假"但文档说null条件检查返回null,而不是false.
背景
我正在开发一个简单的 Windows 服务,它监视某些目录的文件创建事件并记录这些事件 - 长话短说,以确定文件是否从目录 A复制到目录 B。如果 X 时间后文件不在目录 B 中,将发出警报。
问题是我只有在确定文件是否已进入目录 B 时才能继续获取信息 - 我假设两个具有相同名称的文件是相同的,但是因为有超过 60 个目录 A和单个目录 B - 并且任何目录 A 中的文件可能会意外地与另一个目录相同(按日期或顺序),这不是一个安全的假设......
例子
假设,例如,我在目录 C:\Test 中存储了一个文件“E17999_XXX_2111.txt”的日志。我将存储此文件的文件名、文件路径、文件创建日期、文件长度和 BOM。
30 秒后,我检测到在目录 C:\FinalDestination 中创建了文件“E17999_XXX_2111.txt”...现在我有确定是否的任务;
a) 该文件与在 C:\Test 中创建的文件相同,因此我可以将第一个日志更新为完整并且不再担心它。
b)文件不一样,我不知何故错过了前面的步骤 - 因此我可以忽略这个文件,因为它已经找到了通往目标目录的路。
研究
因此,为了确定在目标中创建的文件是否与在第一个实例中创建的文件完全相同,我进行了一些研究并找到了以下选项:
a) 文件名比较
b) 长度比较
c) 创建日期比较
d) 逐字节比较
e) 哈希比较
问题
a) 正如我上面所说,单独使用文件名太冒昧了。
b) 同样,仅仅因为文件内容的长度相同,并不一定意味着文件实际上相同。
c) 问题在于复制的文件在技术上是一个新文件,因此创建日期会发生变化。无论出现在目录 A 和目录 B 中的文件之间经过的时间如何,我都希望将第一个日志设置为完整。
d) 除了这种方法非常慢这一事实之外,如果第二个文件以某种方式改变了编码,似乎还有一个问题——例如在 ANSII 和 ASCII 之间,这会导致像 ascii 引号这样的东西的字节不匹配
我不想假设仅仅因为 ASCII ' 已更改为 …
我在单元测试中遇到了关于处理DateTime.Now的问题的接受答案,其中包含以下代码示例:
private readonly Func<DateTime> _nowProvider;
public SomeClass(Func<DateTime> nowProvider)
{
_nowProvider = nowProvider;
}
public bool Foo()
{
return (_nowProvider().DayOfWeek == DayOfWeek.Sunday);
}
Run Code Online (Sandbox Code Playgroud)
实例化如下:
var s = new SomeClass(() => DateTime.Now);
Run Code Online (Sandbox Code Playgroud)
我Func<T>在C#中使用的并不多,所以我想我会看看它的Microsoft文档,它有以下几点:
您可以使用此委托表示可以作为参数传递的方法,而无需显式声明自定义委托.封装的方法必须对应于此委托定义的方法签名.这意味着封装的方法必须没有参数,并且必须返回一个值.
为什么在示例中传递一个Func<DateTime>实例化Class(() => DateTime.Now)的构造函数会更有益
而不是简单地传入一个DateTime实例化为Class(DateTime.Now)构造函数的参数?
根据上面提到的Microsoft文档,LINQ lambda构造函数也接受了Func<T>论证,我的经验证明它们非常灵活,但我不明白为什么?
有没有办法使用 string.Join 创建一个制表符分隔的字符串并将其输出到文件中?
我这样做:
string.Join(@"\t", array);
Run Code Online (Sandbox Code Playgroud)
但在我的文件中(我试过 .txt 和 .csv),结果如下:
one\ttwo\tthree\tfour\tfive
Run Code Online (Sandbox Code Playgroud)
我认为这是因为分隔符不是标准的单字符分隔符,因为它使用管道或逗号可以正常工作。
我知道还有很多其他方法可以做到这一点,但我希望使用 string.Join 创建一个通用的解决方案,这可能是不可能的。
谢谢!