小编Mat*_*son的帖子

为什么这段代码会给出“可能的空引用返回”编译器警告?

考虑以下代码:

using System;

#nullable enable

namespace Demo
{
    public sealed class TestClass
    {
        public string Test()
        {
            bool isNull = _test == null;

            if (isNull)
                return "";
            else
                return _test; // !!!
        }

        readonly string _test = "";
    }
}
Run Code Online (Sandbox Code Playgroud)

当我构建它时,标有的行!!!给出了编译器警告:warning CS8603: Possible null reference return.

我觉得这有点令人困惑,因为它_test是只读的并且初始化为非空。

如果我将代码更改为以下内容,警告就会消失:

        public string Test()
        {
            // bool isNull = _test == null;

            if (_test == null)
                return "";
            else
                return _test;
        }
Run Code Online (Sandbox Code Playgroud)

谁能解释这种行为?

c# nullable-reference-types

81
推荐指数
4
解决办法
8344
查看次数

为什么Enumerable.Single()会迭代所有元素,即使已找到多个项目?

在分析我们的一个应用程序时,我们在一些代码中发现了一个神秘的减速,我们正在调用Enumerable.Single(source, predicate)一个大型集合,它有多个项目与集合开头附近的谓词相匹配.

调查显示,执行情况Enumerable.Single()如下:

public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) 
{
        TSource result = default(TSource);
        long count = 0;
        // Note how this always iterates through ALL the elements:
        foreach (TSource element in source) { 
            if (predicate(element)) {
                result = element;
                checked { count++; }
            }
        }
        switch (count) {
            case 0: throw Error.NoMatch();
            case 1: return result;
        }
        throw Error.MoreThanOneMatch();
    }
Run Code Online (Sandbox Code Playgroud)

该实现将遍历序列的每个元素,即使多个元素已经与谓词匹配.

以下实现似乎会产生相同的结果:

public static TSource Single<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) …
Run Code Online (Sandbox Code Playgroud)

c# linq .net-4.0

63
推荐指数
3
解决办法
2371
查看次数

如何为起始页启用"动态内容"?

在Visual Studio 2013的起始页上,有一个标题为"公告"的部分.

在该部分下面说:

及时了解有关Visual Studio的公告.要查看公告,请启用动态内容.

我的问题很简单:我在哪里启用"动态内容"?

还有一个名为"产品视频"的部分.在它下面是以下消息:

我们有很多精彩的内容可以向您展示,但我们需要您的许可才能保持更新.

如果您启用"动态内容",这也会启用吗?或者我需要启用另一个设置吗?

visual-studio-2013

43
推荐指数
1
解决办法
3818
查看次数

为什么IEnumerator.Current的错误处理与IEnumerator <T> .Current不同?

我原本以为为实现的空集合执行以下代码IEnumerable<T>会抛出异常:

var enumerator = collection.GetEnumerator();
enumerator.MoveNext();
var type = enumerator.Current.GetType(); // Surely should throw?
Run Code Online (Sandbox Code Playgroud)

因为集合是空的,所以访问IEnumerator.Current无效,我本来期望一个例外.但是,没有例外List<T>.

这是允许的文档IEnumerator<T>.Current,其中指出Current在以下任何条件下未定义:

  • 枚举器在创建枚举数之后立即定位在集合中的第一个元素之前.在读取Current的值之前,必须调用MoveNext以将枚举数推进到集合的第一个元素.
  • 对MoveNext的最后一次调用返回false,表示集合的结束.
  • 由于集合中所做的更改(例如添加,修改或删除元素),枚举器无效.

(我假设"未能抛出异常"可归类为"未定义行为"......)

但是,如果你做同样的事情,但使用一个IEnumerable,你会得到一个例外.此行为由文档IEnumerator.Current指定,其中指出:

  • 如果对MoveNext的最后一次调用返回false,则当前应该抛出InvalidOperationException,这表示集合的结束.

我的问题是:为什么会有这种差异?我不知道有一个很好的技术原因吗?

这意味着看起来相同的代码可以表现得非常不同,具体取决于它是否正在使用,IEnumerable<T>或者IEnumerable如下面的程序所示(注意代码内部showElementType1()showElementType1()相同):

using System;
using System.Collections;
using System.Collections.Generic;

namespace ConsoleApplication2
{
    class Program
    {
        public static void Main()
        {
            var list = new List<int>();

            showElementType1(list); // Does not throw an exception.
            showElementType2(list); // Throws …
Run Code Online (Sandbox Code Playgroud)

c# ienumerable

26
推荐指数
1
解决办法
2490
查看次数

如果struct包含DateTime字段,为什么LayoutKind.Sequential的工作方式不同?

如果struct包含DateTime字段,为什么LayoutKind.Sequential的工作方式不同?

请考虑以下代码(必须使用"unsafe"启用的编译器应用程序):

using System;
using System.Runtime.InteropServices;

namespace ConsoleApplication3
{
    static class Program
    {
        static void Main()
        {
            Inner test = new Inner();

            unsafe
            {
                Console.WriteLine("Address of struct   = " + ((int)&test).ToString("X"));
                Console.WriteLine("Address of First    = " + ((int)&test.First).ToString("X"));
                Console.WriteLine("Address of NotFirst = " + ((int)&test.NotFirst).ToString("X"));
            }
        }
    }

    [StructLayout(LayoutKind.Sequential)]
    public struct Inner
    {
        public byte First;
        public double NotFirst;
        public DateTime WTF;
    }
}
Run Code Online (Sandbox Code Playgroud)

现在如果我运行上面的代码,我得到类似于以下的输出:

struct = 40F2CC的
地址First = 40F2D4的
地址NotFirst的地址= 40F2CC

注意,First的地址与struct的地址不同; 然而,NotFirst的地址一样的结构的地址.

现在注释掉结构中的"DateTime WTF"字段,然后再次运行它.这一次,我得到的输出类似于:

struct …

c# datetime marshalling structlayout

21
推荐指数
2
解决办法
8480
查看次数

为什么"Func <bool> test = value?F:F"无法编译?

我已经看到了类似的问题,但它们涉及不同类型,所以我认为这是一个新问题.

请考虑以下代码:

public void Test(bool value)
{
    // The following line provokes a compiler error:
    // "Type of conditional expression cannot be determined because there is 
    // no implicit conversion between 'method group' and 'method group".

    Func<bool> test = value ? F : F;
}

public bool F()
{
    return false;
}
Run Code Online (Sandbox Code Playgroud)

现在,根据C#3.0标准,

?:运算符的第二个和第三个操作数控制条件表达式的类型.设X和Y是第二个和第三个操作数的类型.然后,

如果X和Y是相同的类型,那么这是条件的类型否则,如果从X到Y存在隐式转换(第6.1节),而不是从Y到X,则Y是条件表达式的类型.否则,如果从Y到X存在隐式转换(第6.1节),而不是从X到Y,则X是条件表达式的类型.否则,无法确定表达式类型,并发生编译时错误.

在我看来,在我的示例代码中,X和Y必须是相同的类型,因为它们是同一个实体Func.那为什么不编译呢?

c#

20
推荐指数
2
解决办法
1897
查看次数

在代码分析中使用Microsoft.Bcl.Async会导致错误

我正在尝试使用Microsoft.Bcl.Async和代码分析,但是当我运行代码分析时,我得到一个或多个错误.

我正在使用Visual Studio 2012和Update 2.

这对我来说很容易重现:

  1. 创建一个新的默认控制台应用程序.Net 4.
  2. 右键单击References然后选择Manage NuGet Packages...
  3. 单击OnlineasyncSearch Online框中键入.
  4. 你应该看到Async for .Net Framework 4 ....点击Install并接受所有问题.
  5. 添加到Main()一行说:TaskEx.Delay(1000);和ausing System.Threading.Tasks;
  6. 转到项目属性,代码分析部分并勾选Enable Code Analysis on Build.
  7. 编译程序.

我收到两个代码分析错误:

CA0052运行代码分析时出错CA0052:未选择任何目标.[错误和警告](全球)

CA0055运行代码分析CA0055时出错:无法加载ConsoleApplication2.exe.读取模块"ConsoleApplication2"时遇到以下错误:无法解析成员引用:[Microsoft.Threading.Tasks,Version = 1.0.12.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a] System.Threading.Tasks.TaskEx :: Delay.[错误和警告](全球)

我为其他测试程序得到了不同的代码分析错误.我试过的基本Windows窗体应用程序给了我:

CA0001错误运行代码分析CA0001:读取模块"AsyncForNet4"时遇到以下错误:无法解析成员引用:[Microsoft.Threading.Tasks,Version = 1.0.12.0,Culture = neutral,PublicKeyToken = b03f5f7f11d50a3a] System.Threading. Tasks.TaskEx ::延迟.[错误和警告](全球)

两个问题:

  1. 其他人可以重现这个问题吗?
  2. 有人有解决方案吗?

c# code-analysis fxcop base-class-library

20
推荐指数
1
解决办法
5477
查看次数

Windows API似乎比BinaryWriter快得多 - 我的测试是否正确?

[编辑]

感谢@VilleKrumlinde,我修复了一个错误,我在尝试避免代码分析警告时不小心引入了这个错误.我不小心打开了"重叠"文件处理,它不断重置文件长度.现在已修复,您可以FastWrite()多次为同一个流调用而不会出现问题.

[结束编辑]


概观

我正在做一些时序测试,以比较两种不同的方式将结构数组写入磁盘.我相信人们认为,与其他事物相比,I/O成本是如此之高,以至于不值得花太多时间优化其他事情.

但是,我的时间测试似乎表明不是这样.要么我犯了一个错误(这是完全可能的),要么我的优化确实非常重要.

历史

首先是一些历史记录:此FastWrite()方法最初是在几年前编写的,用于支持将结构写入遗留C++程序所使用的文件,我们仍然将其用于此目的.(还有一个相应的FastRead()方法.)它的编写主要是为了更容易将blittable结构数组写入文件,其速度是次要问题.

不止一个人告诉我,这样的优化并不比使用a更快BinaryWriter,所以我终于咬了一口子并进行了一些时序测试.结果让我感到惊讶......

似乎是我的FastWrite()方法是30 -比同等使用快50倍BinaryWriter.这看起来很荒谬,所以我在这里发布我的代码,看看是否有人能找到错误.

系统规范

  • 测试了x86 RELEASE构建,从调试器的OUTSIDE运行.
  • 在Windows 8,x64,16GB内存上运行.
  • 在普通硬盘(不是SSD)上运行.
  • 在Visual Studio 2012中使用.Net 4(安装了.Net 4.5)

结果

我的结果是:

SlowWrite() took 00:00:02.0747141
FastWrite() took 00:00:00.0318139
SlowWrite() took 00:00:01.9205158
FastWrite() took 00:00:00.0327242
SlowWrite() took 00:00:01.9289878
FastWrite() took 00:00:00.0321100
SlowWrite() took 00:00:01.9374454
FastWrite() took 00:00:00.0316074
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,这似乎表明FastWrite()该运行速度提高了50倍.

这是我的测试代码.运行测试后,我做了这两个文件的二进制比较来验证它们确实是相同的(即FastWrite()SlowWrite()生产相同的文件).

看看你能做些什么.:)

using System;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using …
Run Code Online (Sandbox Code Playgroud)

c# optimization filestream

18
推荐指数
1
解决办法
1413
查看次数

是否可以在 .NET Framework 4.8 和 .Net Standard 2.0 中使用 C#11“required”修饰符?

我希望能够将新的 C#11required修饰符与 .NET Framework 4.8 和 .Net Standard 2.0 一起使用。

我使用的是 Visual Studio 2022 版本 17.4。这可能吗?

.net c#

18
推荐指数
1
解决办法
3819
查看次数

使用FileStream.ReadAsync()时,我应该以异步模式打开文件吗?

执行异步I/O的旧.Net方式FileStream是使用FileStream.BeginRead()FileStream.EndRead().

状态的MSDN文档FileStream.BeginRead():

FileStream提供两种不同的操作模式:同步I/O和异步I/O. 虽然可以使用其中任何一种,但底层操作系统资源可能仅允许以这些模式之一进行访问.

默认情况下,FileStream会同步打开操作系统句柄.在Windows中,这会降低异步方法的速度.如果使用异步方法,请使用FileStream(String,FileMode,FileAccess,FileShare,Int32,Boolean)构造函数.

.Net 4.5x对执行异步I/O的方式FileStream是使用Stream.ReadAsync().

MSDN文档FileStream.ReadAsync()直接链接到文档的链接Stream.ReadAsync().本文档未提及在异步模式下打开文件的任何需要; 实际上,文档中的示例代码显然没有这样做.

因此,我假设在使用时File.ReadAsync()不需要以异步模式打开文件.

这个假设是否正确?

[编辑]

我刚刚发现了一篇关于使用Async for File Access的MSDN文章.

这表明:

本主题中的示例使用FileStream类,该类具有导致在操作系统级别发生异步I/O的选项.通过使用此选项,您可以避免在许多情况下阻止ThreadPool线程.

要启用此选项,请在构造函数调用中指定useAsync = true或options = FileOptions.Asynchronous参数.

所以,现在我在想,我应该可以打开该文件在异步模式......如果是这样,这是有点遗憾的是,在文档中提供的示例代码ReadAsync()不能打开该文件异步!

c# filestream beginread async-await

16
推荐指数
1
解决办法
2243
查看次数