小编Dav*_*ave的帖子

任何人都可以解释为什么C#中的Dictionary <>不像STL中的map <T,U>那样工作?

去年我第一次开始使用C#进行编程时,我立即寻找了与STL相同的地图,并学习了Dictionary.

更新了下面的垃圾,我完全错了.我与STL的地图的经验是,我讨厌当我要求它的价值,如果关键在地图上没有,它会自动创建值类型(无论其默认构造函数所做的那样),并将其添加到地图中.然后我必须在代码中检查这个条件并抛出异常.

字典<>使整个shebang正确 - 如果键不存在,它会在您请求值时抛出异常,或者如果不是,则自动添加它并且您想要设置该值.

但你们都已经知道了.我应该在发布之前编写我的单元测试并让自己感到尴尬.:)他们现在写的!

现在我喜欢Dictionary和all,但是现在最让我烦恼的是,如果键不在Dictionary中,它会抛出KeyNotFoundException.因此,我总是需要编写如下代码:

Dictionary<string,string> _mydic;

public string this[string key]
{
  get {
    return _mydic[key]; // could throw KeyNotFoundException
  }
  set {
    if( _mydic.ContainsKey( key))
      _mydic[key] = value;
    else
      _mydic.Add( key, value);
  }
}
Run Code Online (Sandbox Code Playgroud)

如果键不存在,为什么Dictionary不会自动添加键值对,如STL的映射?

现在有趣的是,在以前的生活中,我常常生气,因为我经常不得不试图阻止地图这样做.我想我现在的用例有点不同.

c# dictionary stl map

5
推荐指数
1
解决办法
1149
查看次数

无法让 NUnit 的 Assert.Throws 正常工作

我可以发誓我已经使用 NUnit 的 Assert.Throws 来确定某个方法是否抛出特定的异常,但我的记忆以前已经失败了。我在 SO 上阅读了这篇文章,但它没有回答我的问题,因为我知道正确的语法,并且我不想对返回的异常执行任何操作(我不想查看异常的成员,尽管这可能会很有用)。

我编写了单元测试来证明我对 Dictionary 的使用缺乏理解,并且无法让它处理抛出的 KeyNotFoundException。我在运行时遇到了未处理的 KeyNotFoundException 错误,而不是 NUnit 捕获它并通过测试。我确认我没有将 VS IDE 设置为在抛出的 .NET 异常时中断。

我尝试过这两种方法:

Assert.Throws( typeof(KeyNotFoundException), () => value = prefs["doesn't exist"]);
Run Code Online (Sandbox Code Playgroud)

Assert.Throws<KeyNotFoundException>( () => value = prefs["doesn't exist"]);
Run Code Online (Sandbox Code Playgroud)

但两者都会导致未处理的异常。我在这里缺少什么?

更新似乎其他人无法重现这一点。这是一个屏幕截图:

替代文本

nunit dictionary unit-testing exception keynotfoundexception

5
推荐指数
1
解决办法
8475
查看次数

Visual Studio 2008令人烦恼的块注释自动处理

我读了Visual Studio 2008烦恼的精彩帖子,但没有看到这个.它让我疯狂.现在,我意识到有些人使用像这样的块注释来获取函数文档等:

/*
 *
 *
 *
 */
Run Code Online (Sandbox Code Playgroud)

但是你知道,这是VS2008,现在我们可以使用///.我唯一一次曾经觉得有必要使用C风格的注释是,当我有一些垃圾或测试代码,我暂时想删除.当我第一次执行时,它绝对让我疯狂/*,然后当我在测试代码之后添加一行时,它会在*之后自动放置一个空格,最后我得到了:* /.所以我最终总是需要退格来完成块评论.

我查看了VS2008 IDE中的所有C#编辑器设置,但没有找到任何相关内容.

这是否会让其他任何人在这里疯狂,或者我变成了一个代号?

c# visual-studio-2008

5
推荐指数
1
解决办法
758
查看次数

使用字节数组的扩展方法时遇到问题

我正在使用一个发回图像的设备,当我请求图像时,在图像数据之前有一些未记录的信息.我只能通过查看二进制数据并识别内部的图像标题信息来实现这一点.

我最初有一个普通的方法,并将其转换为扩展方法.这里的原始问题与编译器抱怨没有将Array作为第一个参数(我有Byte [])有关,但事实证明我犯了错误而忘记删除调用代码中的第一个参数.换句话说,我曾经有过:

Byte[] new_buffer = RemoveUpToByteArray(buffer, new byte[] { 0x42, 0x4D });
Run Code Online (Sandbox Code Playgroud)

在更改为扩展方法后,我错误地使用了:

buffer.RemoveUpToByteArray( buffer, new byte[] { 0x42, 0x4D });
Run Code Online (Sandbox Code Playgroud)

无论如何,现在这一切都已修复,因为我在将代码示例输入SO时意识到了我的错误. 但是,我有一个新问题,就是缺乏对扩展方法和引用与值类型的理解.这是代码:

public static void RemoveFromByteArrayUntil(this Byte[] array, Byte[] until)
{
    Debug.Assert(until.Count() > 0);
    int num_header_bytes = until.Count();
    int header_start_pos = 0; // the position of the header bytes, defined by [until]
    byte first_header_byte = until[0];
    while(header_start_pos != -1) {
        header_start_pos = Array.IndexOf(array, first_header_byte, header_start_pos);
        if(header_start_pos == -1)
            break;
        // if we get here, then we've found …
Run Code Online (Sandbox Code Playgroud)

c# extension-methods bytearray

5
推荐指数
1
解决办法
6467
查看次数

MEF的CompositionContainer.ComposeParts - 加载可以解决的任何内容,并忽略错误

到目前为止,MEF最大的问题是,当我在插件加载器包装器中编写部件时,在发现其中一个程序集的导入解决问题时完全加载.理想情况下,我希望ComposeParts能够展示某种"忽略和继续"行为,因为理想的用户体验需要加载尽可能多的插件,并且只需在特定插件无法加载时记录事件.我无法在任何地方的文档中找到有关此信息.

如果您对如何解决这个问题有任何其他建议,我正在听!

.net plugins mef inversion-of-control

5
推荐指数
1
解决办法
4608
查看次数

为什么我不能使用AsyncMethodCaller?

这是我第一次使用需要通过回调方法将值返回到另一个类的线程.我已经阅读了它,似乎每个人都在使用AsyncMethodCaller.然而,即使我已经为我的项目添加了必要的参考,VS 2008认为它是未定义的......我还有什么可能在这里做错了?

c# multithreading .net-3.5

5
推荐指数
1
解决办法
6998
查看次数

使用数据绑定WPF ComboBox诊断性能问题

我今天早上一直在和一个"慢"的WPF ComboBox作战,并且很想知道是否有人有调试这样一个问题的技巧.

假设我有两个组合框,A和B.当A改变时,B中的项也会改变.每个ComboBox都有他们的SelectedItem和ItemsSource数据绑定,如下所示:

<ComboBox Grid.Column="1" ItemsSource="{Binding Names}" SelectedItem="{Binding CurrentName, Mode=TwoWay}" Margin="3" MinWidth="100" />
<ComboBox Grid.Column="1" Grid.Row="1" ItemsSource="{Binding SubNames}" SelectedItem="{Binding CurrentSubName, Mode=TwoWay}" Margin="3" MinWidth="100" />
Run Code Online (Sandbox Code Playgroud)

每当B中的列表需要更改时,我通过清除子名称然后根据A中的SelectedItem重新添加条目来执行此操作.这样做是因为使用new覆盖SubNames ObservableCollection<string>会破坏数据绑定.

一台计算机上的所有内容都按照您的预期运行.选择A,然后单击B并立即弹出新项目.在另一台计算机上,当我这样做时,在渲染ComboBox之前最多有5秒的暂停.项目数量完全相同.一个不同之处在于,在慢速机器上,后台正在进行硬件通信.我冻结了所有这些线程并没有帮助.

我最大的问题是我无法弄清楚在哪里开始寻找.我需要查看系统在点击ComboBox时正在做什么.我正在使用数据绑定,所以我无法在任何地方放置断点.我确实试图改变我的SubNames声明

public ObservableCollection<string> SubNames { get; set; }
Run Code Online (Sandbox Code Playgroud)

private ObservableCollection<string> subnames_ = new ObservableCollection<string>();
public ObservableCollection<string> SubNames
{
  get { return subnames_; }
  set { subnames_ = value; }
}
Run Code Online (Sandbox Code Playgroud)

然后在getter和setter中放置断点以查看是否有过多的读取或写入,但没有.

任何人都可以建议我下一步尝试确定这种放缓的来源吗?我不相信它与ComboBox库存模板有任何关系,如本文所述.

data-binding wpf performance combobox

5
推荐指数
1
解决办法
1467
查看次数

在Visual Studio 2010中需要高效的黑客调试

我经常Debug -> Exceptions -> check CLR Exceptions在调试会话期间使用.有时会抛出并处理异常,但我真的想找到异常的来源.为了做到这一点,我没有看到我不关心的第一次机会异常,我启动我的应用程序,然后检查CLR例外:

在此输入图像描述

这变得非常乏味,我很想在我的VS2010工具栏切换按钮,可以让我在将只设置/复位CLR例外,而无需钥匙CTRL+ D,E,选中该复选框,然后单击确定(和然后再次执行相同的过程以关闭异常).我进入了工具栏自定义,但我只能得到一个按钮,显示"例外"对话框.这显然不如击中CTRL+ D,效率低E.

有谁知道另一种方法来添加这个?它需要一个VS插件吗?按键映射也很不错.

我从来没有在VS中使用过Macro Recorder,但也许这是一个必要的地方?

customization exception toolbar visual-studio-2010

5
推荐指数
1
解决办法
246
查看次数

解决 COM 相关错误 0x80040154 的技术?

更新了更多调试信息

我正在运行一个我没有源代码的专有软件包,它有一个基于 COM 的插件接口。我有一个 COM 可见的 .NET 程序集,该应用程序在一台计算机上成功加载,但在另一台计算机上无法加载。

过去两天我一直在研究这个问题,我觉得我在 COM 环境中漫无目的地游荡。在没有加载我的插件的系统上,当我使用 时regasm /codebase /tlb,tlb 生成并成功注册。

当我查看唯一可用的日志文件时,它提到它无法创建对象,并返回错误代码 0x80040154。

我无法弄清楚为什么无法创建对象,希望有人可以提出一些调试策略。这是我已经尝试过的,但没有成功:

  • 将我的 DLL 及其依赖项从工作计算机复制到非工作计算机
  • 在非工作计算机上安装VS2010(工作计算机已安装)
  • 比较我的 DLL 的 Dependency Walker 的结果及其在两台计算机上的依赖项(它们是相同的)
  • 使用 ListDLL。两个系统加载相同的 DLL
  • 运行进程监视器并在运行时过滤程序集的 CLSID regasm /codebase /tlb。除了 PID 和日期戳之外,两个日志都是相同的,即使工作系统创建了 tlb 并成功注册,非工作系统注册了程序集,但没有创建 tlb。
  • 运行进程监视器并在运行应用程序时过滤程序集的 CLSID。工作系统在日志中有几个条目,但非工作系统没有,我相信这是预期的,因为 tlb 没有被创建。
  • 查看工作系统上的 OleView,其中列出了程序集,并在其下方列出了类型库。非工作系统列出了程序集,但没有关联类型库。见下文。

以下是工作和非工作系统上 OleView 中程序集条目之间的差异:

  • 工作系统在我假设对应于生成和注册的类型库的程序集下有一个条目。非工作系统没有。
  • 非工作系统上的 _Object 在 CLSID 下有一个名为 的额外值InprocServer32[InprocServer32] = (gibberish here)
  • 非工作系统上的 IConnectionPointContainer 具有与InprocServer32上述相同的条目
  • IDispatch、IManagedObject 和 IProvideClassInfo 相同

我会查看注册表,也许我需要删除那些额外的条目并再次尝试运行 regasm?

编辑 - …

c# com interop com-interop .net-4.0

5
推荐指数
1
解决办法
3584
查看次数

需要为OpenWRT中的IPC消息队列增加缓冲区

我刚刚学习如何使用消息队列,但我在使用它们时遇到了一些困难。我使用两个完全独立的应用程序来进行测试——一个是“发送者”,另一个是“接收者”。

当我运行发送器时,它向管道发送 15 个字符串,但随后失败并出现“资源暂时不可用”错误。我只需要在接收方消费消息,但为什么只有 15 条消息?我可能会发送大量消息,因此我想将其增加到更大的数量,例如 1000 条左右。

我尝试将消息队列大小设置为 32767,因此我期望至少为 31,但显然msg_qbytes与可以缓冲的消息数量无关。

发送者代码如下所示:

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/msg.h>
#include <unistd.h>
#include <string.h>

#define MESSAGE_SIZE 1024

typedef struct msgbuf
{
    long mtype;
    char mtext[MESSAGE_SIZE];
};

int main(int argc, char *argv[]) {
    int msgid;
    int ret;
    struct msqid_ds msg_settings;
    long key;
        struct msgbuf msg;

    key = strtol(argv[1], NULL, 10);
    // print the message queue ID for reading via msgrcv
    printf( "Getting message queue with key = …
Run Code Online (Sandbox Code Playgroud)

c linux openwrt sysv-ipc

5
推荐指数
1
解决办法
8284
查看次数