相关疑难解决方法(0)

C#在foreach中重用变量是否有原因?

在C#中使用lambda表达式或匿名方法时,我们必须警惕对修改后的闭包陷阱的访问.例如:

foreach (var s in strings)
{
   query = query.Where(i => i.Prop == s); // access to modified closure
   ...
}
Run Code Online (Sandbox Code Playgroud)

由于修改后的闭包,上面的代码将导致Where查询中的所有子句都基于最终值s.

正如这里所解释的那样,这是因为上面循环中s声明的变量foreach在编译器中被翻译成这样:

string s;
while (enumerator.MoveNext())
{
   s = enumerator.Current;
   ...
}
Run Code Online (Sandbox Code Playgroud)

而不是像这样:

while (enumerator.MoveNext())
{
   string s;
   s = enumerator.Current;
   ...
}
Run Code Online (Sandbox Code Playgroud)

正如这里所指出的,循环外声明变量没有性能优势,在正常情况下,我能想到这样做的唯一原因是你计划在循环范围之外使用变量:

string s;
while (enumerator.MoveNext())
{
   s = enumerator.Current;
   ...
}
var finalString = s;
Run Code Online (Sandbox Code Playgroud)

但是,foreach循环中定义的变量不能在循环外使用: …

c# foreach lambda scope anonymous-methods

1631
推荐指数
4
解决办法
10万
查看次数

你在C#或.NET中看到的最奇怪的角落是什么?

我收集了一些角落案例和脑筋急转弯,并且总是希望听到更多.该页面仅涵盖C#语言位和bobs,但我也发现核心.NET的东西也很有趣.例如,这是一个不在页面上,但我觉得不可思议的:

string x = new string(new char[0]);
string y = new string(new char[0]);
Console.WriteLine(object.ReferenceEquals(x, y));
Run Code Online (Sandbox Code Playgroud)

我希望打印False - 毕竟,"new"(带引用类型)总是会创建一个新对象,不是吗?C#和CLI的规范都表明它应该.好吧,不是在这种特殊情况下.它打印True,并在我测试过的每个版本的框架上完成.(我没有在Mono上尝试过,诚然......)

需要明确的是,这只是我正在寻找的那种事情的一个例子 - 我并不是特别想要讨论这种奇怪的事情.(它与正常的字符串实习不同;特别是,当调用构造函数时,通常不会发生字符串实习.)我真的要求类似的奇怪行为.

还有其他宝石潜伏在那里吗?

.net c#

322
推荐指数
27
解决办法
12万
查看次数

为什么这个字符串扩展方法不会抛出异常?

我有一个C#字符串扩展方法,它应返回IEnumerable<int>字符串中子字符串的所有索引.它完美地用于其预期目的,并返回预期的结果(由我的一个测试证明,虽然不是下面的一个),但另一个单元测试发现它有一个问题:它不能处理空参数.

这是我正在测试的扩展方法:

public static IEnumerable<int> AllIndexesOf(this string str, string searchText)
{
    if (searchText == null)
    {
        throw new ArgumentNullException("searchText");
    }
    for (int index = 0; ; index += searchText.Length)
    {
        index = str.IndexOf(searchText, index);
        if (index == -1)
            break;
        yield return index;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是标记问题的测试:

[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Extensions_AllIndexesOf_HandlesNullArguments()
{
    string test = "a.b.c.d.e";
    test.AllIndexesOf(null);
}
Run Code Online (Sandbox Code Playgroud)

当测试针对我的扩展方法运行时,它会失败,标准错误消息表明该方法"没有抛出异常".

这很令人困惑:我已明确传入null函数,但由于某种原因,比较null == null正在返回false.因此,不会抛出异常并且代码会继续.

我已经确认这不是测试的错误:在我的主项目中通过调用Console.WriteLinenull比较if块运行该方法时,控制台上没有显示任何内容,并且catch我添加的任何块都没有捕获到任何异常.而且,使用string.IsNullOrEmpty而不是== null …

c# comparison ienumerable null argumentnullexception

117
推荐指数
2
解决办法
6609
查看次数

如何在实体框架中查询空值?

我想执行这样的查询

   var result = from entry in table
                     where entry.something == null
                     select entry;
Run Code Online (Sandbox Code Playgroud)

并得到一个IS NULL生成.

编辑:在前两个答案后,我觉得有必要澄清我正在使用实体框架而不是Linq to SQL.object.Equals()方法似乎不适用于EF.

编辑2:上述查询按预期工作.它正确生成IS NULL.然而,我的生产代码是

value = null;
var result = from entry in table
                         where entry.something == value
                         select entry;
Run Code Online (Sandbox Code Playgroud)

并且生成的SQL是something = @p; @p = NULL.似乎EF正确地转换了常量表达式,但是如果涉及变量,它就像正常比较一样处理它.实际上是有道理的.我会结束这个问题

.net ado.net entity-framework

107
推荐指数
6
解决办法
10万
查看次数

C#(.NET)设计缺陷

C#或.NET Framework中一些最大的设计缺陷是什么?

示例:没有非可空字符串类型,您必须在从IDataReader获取值时检查DBNull.

.net c#

85
推荐指数
21
解决办法
1万
查看次数

重写方法的C#可选参数

似乎在.NET Framework中,覆盖方法时可选参数存在问题.下面代码的输出是:"bbb""aaa".但我期待的输出是:"bbb""bbb".有解决方案.我知道它可以用方法重载解决,但想知道原因.此外,代码在Mono中运行良好.

class Program
{
    class AAA
    {
        public virtual void MyMethod(string s = "aaa")
        {
            Console.WriteLine(s);
        }

        public virtual void MyMethod2()
        {
            MyMethod();
        }
    }

    class BBB : AAA
    {
        public override void MyMethod(string s = "bbb")
        {
            base.MyMethod(s);
        }

        public override void MyMethod2()
        {
            MyMethod();
        }
    }

    static void Main(string[] args)
    {
        BBB asd = new BBB();
        asd.MyMethod();
        asd.MyMethod2();
    }
}
Run Code Online (Sandbox Code Playgroud)

.net c# overriding optional-parameters

71
推荐指数
6
解决办法
2万
查看次数

重载运算符==与Equals()

我正在开发一个C#项目,直到现在,我已经使用了不可变对象和工厂来确保Foo始终可以比较类型对象的相等性==.

Foo创建后无法更改对象,并且工厂始终为给定的参数集返回相同的对象.这很好用,在整个代码库中我们假设它==始终用于检查相等性.

现在我需要添加一些引入边缘情况的功能,但这并不总是有效.最简单的方法是operator ==为该类型重载,以便项目中的其他代码都不需要更改.但这让我感觉像代码味道:重载operator ==并且Equals不仅仅是看起来很奇怪,而且我习惯于==检查引用相等性的约定,并Equals检查对象的相等性(或任何术语).

这是一个合理的问题,还是我应该继续超载operator ==

c# equals operator-overloading

44
推荐指数
6
解决办法
3万
查看次数

ElapsedTicks,ElapsedMilliseconds,Elapsed.Milliseconds和Elapsed.TotalMilliseconds之间的区别?(C#)

我在这些之间完全感到困惑4.ElapsedMilliseconds(long),ElapsedTicks(long),Elapsed.TotalMilliseconds(double)和Elapsed.Milliseconds(int)之间有什么区别?

我有一个功能

    {
        Stopwatch sw = new Stopwatch();

        sw.Start();
        MyTimeConsumingAction();
        sw.Stop();

        sw.//what?
    }
Run Code Online (Sandbox Code Playgroud)

如何从秒表对象的已用属性(以毫秒为单位)获取长时间运行的进程所消耗的正确时间?

编辑:我试过msdn文档,但它没有详细说明..

c# performance system.diagnostics stopwatch .net-4.0

38
推荐指数
3
解决办法
2万
查看次数

在C#5中是否改变了foreach对变量的使用?

在这个答案中,https: //stackoverflow.com/a/8649429/1497 Eric Lippert说"我们很有可能在下一版本的C#中解决这个问题;对于开发人员而言,这是一个主要的痛点". foreach循环使用变量.

在下一个版本中,每次运行"foreach"循环时,我们将生成一个新的循环变量,而不是每次都关闭相同的变量.这是一个"突破"的变化,但在绝大多数情况下,"休息"将是修复而不是导致错误.

我无法找到任何表明此更改尚未完成的内容.有没有迹象表明这是foreach循环在C#5中的工作方式?

c# foreach c#-5.0 .net-4.5

37
推荐指数
1
解决办法
5590
查看次数

针对Oracle的C#参数化查询 - 严重且危险的错误!

这是绝对的咆哮.我不敢相信自己的眼睛,我不相信在我之前没有人会发现这个,如果它是C#中的一个真正的错误,所以我把它推出给其他开发者社区告诉我我做错了什么.我确定这个问题会让我说"DOH!" 用我的手掌非常用力地拍打我的头 - 但无论如何......

为了测试,我创建了一个表Test_1,脚本如下:

CREATE TABLE TEST_1 (
  COLUMN1 NUMBER(12) NOT NULL,
  COLUMN2 VARCHAR2(20),
  COLUMN3 NUMBER(12))
TABLESPACE USERS
STORAGE (
  INITIAL 64K
  MAXEXTENTS UNLIMITED
)
LOGGING;
Run Code Online (Sandbox Code Playgroud)

现在我执行以下代码:

var conn = new OracleConnection("connectionblahblah");
conn.Open();
var cmd = conn.CreateCommand();
cmd.CommandText = 
  "insert into Test_1(Column1, Column2, Column3) " +
  "values(:Column1, :Column2, :Column3)";
var p = cmd.Parameters;
p.Add("Column1", 1);
p.Add("Column3", null);
p.Add("Column2", "record 1");
cmd.ExecuteNonQuery();
Run Code Online (Sandbox Code Playgroud)

哇!我收到ORA-01722错误 - "无效号码"!但是怎么了? Column1是数字,值为1,所以很好; Column2是一个字符串,Column3是一个可以为空的列,所以不应该造成任何麻烦......

现在请坐下来......这里的问题是,Column3Column2按照它们被添加到的顺序进行转换OracleParameterCollection.切换它们,并预先!有用! …

c# oracle ora-01722

36
推荐指数
2
解决办法
2万
查看次数