小编Rvd*_*V79的帖子

C#6.0中的Monadic null检查

我偶然发现了一个有趣的网站,其中解决了C#6.0的一些新的(提议的)功能.您可以在这里阅读:可能的C#6.0功能.

我觉得特别有趣的是monadic null检查(也称为null-propagation操作符).根据网站,以下声明

var bestValue = points?.FirstOrDefault()?.X ?? -1;
Run Code Online (Sandbox Code Playgroud)

包含monadic null检查,目前使用这段代码实现:

if (points != null) 
{
  var next = points.FirstOrDefault();
  if (next != null && next.X != null) return next.X;
}   
return -1;
Run Code Online (Sandbox Code Playgroud)

我的第一眼就是,嘿,这里写的是什么?但在查看"旧"代码后,我开始喜欢它了.

但是,我也开始提出一些问题,我想问一下.

  • 我假设这个null传播的运算符是线程安全的.但这实际上是如何进行的?种族条件会被删除还是会持续存在?
  • 该运算符如何处理泛型类型?而且,它如何处理无约束的泛型类型?例如,考虑一下

    var resultAfterNullCheck = x?.Y;
    
    Run Code Online (Sandbox Code Playgroud)

    如果这里的类型Y用引用类型,非可空值类型和可空值类型实例化,那么就没有任何合理的做法(因为我不知道该做什么,因为我根本不知道该怎么做).那么是否会返回默认值?或者它会抛出错误?

  • 在查看站点提供的示例(以及我在上面复制的示例)时,我假设null-propagation运算符的一个主要好处是它只会评估语句一次.然而(也许是由于我对CLR的了解不足),我很好奇它是如何进行的.
    对我来说,第一个评估(如果points等于null)应该触发扩展方法FirstOrDefault()在points不为null时触发,然后将返回类型的evalation设置为null或者不是,否则,X将是回.那么这些实际上是三个评估合二为一?或者我不正确地理解它?这会影响执行速度吗?

换句话说,什么会更快,执行空检查的旧方法,或这个新的可爱运算符?我将在Visual Studio 2015下载完成后立即进行一些研究来检查这一点...但这需要一点耐心......

对这种新的操作员类型有什么想法吗?它真的还是一个提议的,或者我们真的可以期望使用这个新的monadic null检查吗?

编辑
正如Matthew Watson提供了一篇很好的MSDN讨论这个(以及更多)主题的文章,我很好奇它是否提到了我之前关于无约束泛型的问题以及这个算子如何处理它.不幸的是,我还没有找到答案.虽然我认为程序员应该试图阻止使用无约束泛型,但我仍然可以想象这有时是不可行的.如果是这样的话,重新设计是否真的有必要?

c# c#-6.0 null-propagation-operator

23
推荐指数
2
解决办法
4857
查看次数

F#Power问题接受两个参数都是bigints

我目前正在试验F#.在互联网上找到的文章很有帮助,但作为一名C#程序员,我有时遇到我认为我的解决方案会有所帮助的情况,但它没有或只是部分帮助.

因此,我对F#缺乏了解(最有可能的是,编译器的工作方式)可能是我有时会非常惊讶的原因.

例如,我写了一个C#程序来确定完美的数字.它使用欧几里德证明的已知形式,可以从Mersenne Prime 2p-1(2p-1)(其中2p-1是素数,p表示为幂)形成完美数.

由于F#的帮助声明'**'可用于计算功率,但使用浮点,我试图用bitshift运算符创建一个简单的函数(<<<)(注意我编辑了这个代码指出需要):

 let PowBitShift (y:int32) = 1 <<< y;;
Run Code Online (Sandbox Code Playgroud)

但是,在运行测试并寻找性能改进时,我还尝试了一种形式,我记得使用Miranda(一种函数式编程语言),它使用递归和模式匹配器来计算功率.主要的好处是我可以使用变量y作为64位整数,这对于标准的bitshift运算符是不可能的.

    let rec Pow (x : int64) (y : int64) = 
    match y with
        | 0L -> 1L
        | y -> x * Pow x (y - 1L);;
Run Code Online (Sandbox Code Playgroud)

事实证明,这个功能实际上更快,但我不能(还)理解原因.也许这是一个不那么智力的问题,但我仍然很好奇.

那么秒的问题就是,当计算完美数字时,你会遇到这样一个事实:在找到第9个完美数字(由31的幂形成)之后,int64无法显示大数字交叉.我试图找出你是否可以使用BigInteger对象(或bigint类型),但在这里我对F#的了解阻止了我一点.是否有可能创建一个接受两个参数的幂函数?

我目前有这个:

let rec PowBigInt (x : bigint) (y : bigint) = 
    match y with
        | bigint.Zero -> 1I
        | y -> x * Pow x (y - 1I);;
Run Code Online (Sandbox Code Playgroud)

但它抛出了bigint.Zero未定义的错误.所以我也在做错事.0I不被接受作为替代,因为它给出了这个错误:

Non-primitive numeric literal constants cannot be …
Run Code Online (Sandbox Code Playgroud)

f# pattern-matching perfect-numbers

11
推荐指数
3
解决办法
844
查看次数

正则表达式挑战:改变负数的格式

首先,我认为我必须为没有那么多关于正则表达式的知识而道歉(还).我搜索过并搜索过,但没有找到符合我特定挑战的解决方案.

现在问题来了:

我目前正在尝试开发解析器(意思是自己编写).我想在考虑正则表达式时这样做.到目前为止,我已经设法做了很多,但是,我遇到了一个小问题.一元减号和二进制减号.

我十年前在大学学到的是,这应该基于背景.但是,还有一个简单的技巧,我在手工操作时使用它,并将每个一元减去写入不同的格式:

-3 = (0 - 3) 
Run Code Online (Sandbox Code Playgroud)

要么

5 * -3 = 5 * (0 - 3)
Run Code Online (Sandbox Code Playgroud)

有点棘手:

(5--5)-3 = (5 - (0 - 5)) - 3
Run Code Online (Sandbox Code Playgroud)

现在,这是我的问题,是否有可能编写一个正则表达式,通过添加括号和0来将一元减去表达式转换为二进制减去表达式,就像上面提供的示例一样?

也许可能还有另一种方式,但我在这里有点偏见......

评论:首先,我开始用MINUS替换所有减号,如:

expressionBuffer = "-(1-2)-3";
expressionBuffer = Regex.Replace(expressionBuffer, "-", "MINUS");
Run Code Online (Sandbox Code Playgroud)

这产生了一个新的expressionBuffer,它看起来像:

MINUS ( 1 MINUS 2 ) MINUS 3
Run Code Online (Sandbox Code Playgroud)

现在,我尝试使用以下正则表达式捕获二进制' - '运算符:

expressionBuffer = Regex.Replace(
                     expressionBuffer, 
                     @"(?<number>((\d+(\.\d+)?)))\s+MINUS", 
                     "${number} -"
                   );
Run Code Online (Sandbox Code Playgroud)

这会产生:

MINUS ( 1 - 2 ) MINUS 3
Run Code Online (Sandbox Code Playgroud)

第一个MINUS显然是一个一元的运算符(但第二个显然不是!)所以我现在正在寻找一种方法来重写那个以下(第一)格式:

( 0 …
Run Code Online (Sandbox Code Playgroud)

c# regex parsing replace

9
推荐指数
1
解决办法
157
查看次数

Lucas Lehmer优化

我一直在努力使用C#代码优化Lucas-Lehmer素性测试(是的,我正在使用Mersenne primes来计算完美数字.我想知道当前代码可以进一步提高速度.我使用System.Numerics.BigInteger类来保存数字,也许它不是最明智的,我们会看到它.

此代码实际上基于以下网站上的智能:http://en.wikipedia.org/wiki/Lucas%E2%80%93Lehmer_primality_test

这个页面(在时间戳)部分,给出了一些证据来优化分割.

LucasTest的代码是:

public bool LucasLehmerTest(int num)
{
  if (num % 2 == 0)
     return num == 2;
  else
  {
     BigInteger ss = new BigInteger(4);
     for (int i = 3; i <= num; i++)
     {
        ss = KaratsubaSquare(ss) - 2;
        ss = LucasLehmerMod(ss, num);
     }
     return ss == BigInteger.Zero;
  }
Run Code Online (Sandbox Code Playgroud)

}

编辑: 这比使用下面的Mare Infinitus建议的BigInteger类中的ModPow更快.该实施是:

public bool LucasLehmerTest(int num)
{
  if (num % 2 == 0)
     return num == 2;
  else
  {
     BigInteger m = …
Run Code Online (Sandbox Code Playgroud)

c# math primes multithreading perfect-numbers

7
推荐指数
1
解决办法
2004
查看次数

TClientDataSet:如何在更改数据库结构时保留本地数据并使其可用

您好代码爱好者!

我有一个问题,这无疑是由于我的Delphi XE2知识缺乏经验.我会试着在这里解释一下.

介绍:

我有一个带数据的Interbase数据库.该数据库位于远程计算机上.我正在开发的客户端应用程序使用此数据库.由于必须在没有可用的网络连接时使用该应用程序,我必须使用公文包模型.这就是为什么我使用ClientDataSet来检索数据并以XML格式本地存储它.在我看来,使用本地数据库代替XML文件会更容易,但我还是不允许改变它.因此我仍然绑定到XML :(

由于数据的重要性,我希望尽可能保持安全.即使其他开发人员正在更改数据库的内部结构(例如,表中的字段被添加,重命名甚至删除),本地存储的数据仍然必须可用.

我现在做的是,我使用ClientDataSet从数据库中检索元数据.它分别存储在磁盘上.我计划做的下一件事是将数据库中的元数据与存储在本地数据集中的元数据进行比较.当我在字段中发现差异时,我在代码中创建了一个新的数据集,我建立了字段定义并在之后添加数据.换句话说,我只是创建一个新的本地数据集,它符合远程数据库中表的结构.

当我找到列(字段)删除或添加时,这很容易,但是当字段名称或数据类型发生更改时,它会变得有点困难.

我还没有考虑主键,外键和唯一键,但我也觉得必须这样做.

题:

我的问题主要是,我想知道这是否是正确的方法.实现这一点是相当有意义的,在我开始实现这一切之前,我想知道是否还有其他(更方便,更简单)的方法来实现我上面描述的内容.

在我看来,本地可用的数据优先于远程数据库中存储的数据.仅仅因为用户正在处理本地数据而不是直接处理远程数据.

有什么想法吗?我希望我能够充分澄清我的问题,如果没有,请询​​问,我会提供更多细节.我正在使用Interbase XE(SP5)和Delphi XE 2.

database delphi interbase tclientdataset

7
推荐指数
1
解决办法
4428
查看次数