小编Man*_*nia的帖子

是否有可能在C#中创建一个真正弱键的字典?

我正试图坚持WeakKeyedDictionary<,>C#的真实细节......但我遇到了困难.

我意识到这是一个非常重要的任务,但似乎无法声明a WeakKeyedKeyValuePair<,>(如果密钥可达,GC只跟随值引用)使得它看起来似乎不可能.

我看到两个主要问题:

  1. 到目前为止,我所看到的每个实现都没有在收集密钥后修剪值.考虑一下 - 使用这样一个字典的主要原因之一是防止这些值被保留(不仅仅是键!),因为它们无法访问,但在这里它们被强引用指向.

    是的,在词典中添加/删除足够多,它们最终会被替换,但是如果你不这样做呢?

  2. 如果没有一个假设WeakKeyedKeyValuePair<,>(或告诉GC到的另一种方法只标出值,如果关键是可达)是指它的键永远不会被收集的任何值.存储任意值时,这是一个问题.

问题1可以在一个相当不理想/ hackish的方式来解决:使用GC通知等待一个完整的GC完成,然后沿着去修剪字典在另一个线程.这个我半熟的.

但问题2让我难过.我意识到这很容易被"所以不要这样做"所抵消,但我想知道 - 这个问题甚至可以解决吗?

.net c# dictionary garbage-collection weak-references

22
推荐指数
1
解决办法
4459
查看次数

C#中表达式树的ByRef参数

如果我想创建一个使用out参数调用方法的表达式树,然后返回该out值作为结果..我将如何处理它?

以下不起作用(抛出运行时异常),但也许最能说明我正在尝试做的事情:

private delegate void MyDelegate(out int value);
private static Func<int> Wrap(MyDelegate dele)
{
    MethodInfo fn = dele.Method;
    ParameterExpression result = ParameterExpression.Variable(typeof(int));
    BlockExpression block = BlockExpression.Block(
        typeof(int), // block result
        Expression.Call(fn, result), // hopefully result is coerced to a reference
        result); // return the variable
    return Expression.Lambda<Func<int>>(block).Compile();
}

private static void TestFunction(out int value)
{
    value = 1;
}

private static void Test()
{
    Debug.Assert(Wrap(TestFunction)() == 1);
}
Run Code Online (Sandbox Code Playgroud)

我知道这可以在原始IL(或者根本没有运行时编译)中相当容易地解决,但不幸的是,这是一个更大的表达式构建过程的一部分...所以我真的希望这不是一个限制,因为完全重写将不仅仅是一种痛苦.

c# expression-trees

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

无法在C中包含ASM头文件而不会丢失预处理器

精简版:

我希望能够在a中定义汇编程序宏,macros.Sasm()在GNU C中的内部语句中使用它们.

我可以asm(".include \"macros.S\"");在我的C源头附近做到这一点,但我想macros.S通过C预处理器.


长版:

在GCC asm中,*.S文件由C预处理器预处理,允许使用C样式#define等.

在GCC C中,您可以.set通过asm(".include \"myasmheader.S\"");在文件顶部附近写入来包含asm头文件(可能包括asm宏定义,声明等).

以这种方式包含ASM头文件允许您在asm块中使用asm宏.

不幸的是,这样做不会.S在包含的文件上调用C预处理器(正如.include稍后在编译过程中所做的那样),因此#defines不再被替换.

那么有没有办法.S在C文件中正确包含文件?

其他一些编译器支持:

#asm
#include "myasmheader.S"
#endasm
Run Code Online (Sandbox Code Playgroud)

哪个不会出现这样的问题.但是,唉,GCC似乎要求C文件中的所有asm都是字符串形式.

如果没有使用asm(不是一个选项,重度混合asm和c的嵌入式DSP项目),或者在ASM文件中删除C预处理器的使用,可以做些什么呢?

c assembly gcc inline-assembly c-preprocessor

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

在nullables和base类型之间实现运算符 - 我应该吗?

这可能是众所周知和讨论的,但令我惊讶的是,我今天发现你可以在nullables和它们的基类型之间提供你自己的运算符实现.

这意味着您可以struct检查哪个null,并返回true.

现在这在我的情况下会很方便 - 在另一个成员的建议下,我有一个包裹字符串的结构.能够直接将这个包裹的字符串直接比较为null(而不是使用.IsNull或类似的)对我来说更自然,并且意味着从使用字符串转换到这些WrappedStrings通常不需要对代码进行其他更改.

但是......事实上这个特征(我相信)鲜为人知,对于任何思考结构(它都是)超过字符串(它代表)的人都是反直觉的,而且它混淆了ReSharper(structValue == null警告"表达式总是假的) ")让我觉得这可能是一个肮脏但又整洁的技巧橱柜里留下的肮脏伎俩.

所以我想知道,你会采纳它吗?如果没有,你会原谅我这样做吗?或者最好不要走这条路?


public struct StringWrapper
{
    private readonly string str;
    public override string ToString() { return str; }

    public static bool operator ==(StringWrapper a, StringWrapper b) 
    { return a.str == b.str; }
    public static bool operator !=(StringWrapper a, StringWrapper b) 
    { return !(a == b); }
    public static bool operator ==(StringWrapper a, StringWrapper? b)
    {
        if (!b.HasValue || b.Value.str == null) return …
Run Code Online (Sandbox Code Playgroud)

c# nullable operator-overloading

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

在运行时使用不同的资源创建exe的副本

我们希望为我们的客户提供基于我们的客户定制exes的能力.

即,基本上能够使用嵌入在其中的不同xml配置文件制作exe的副本."将它包含在安装中"不是一个选项 - 我们希望这看起来好像是为我们客户的客户定制的.

我目前正在考虑在运行时编写一个dll,包括资源(使用AssemblyBuilder),然后调用ILMerge将其嵌入到最终的exe中,但这比我想要的稍微强一些.

所以这是一个很高的问题,但也许值得问一下:是否有一个.NET库允许修改.NET exe的资源,这可以避免整个"dll持有ILMerge嵌入的资源"位?

或者,是否有更好的方法可以达到既定目标?

.net c# exe

6
推荐指数
1
解决办法
559
查看次数

多个线程在等待一个事件?

(我认为)我想要的是AutoResetEvent多个线程可以等待的平等,所有都可以在设置时恢复.

我知道这可以通过AutoResetEvent每个线程一个并设置每个线程来实现- 但是有更简单的方法吗?一种不依赖于事件句柄数组的方法?

有效的(我认为)我希望能够做到这一点:

private volatile string state;
private MultiEventHandle stateChanged = new MultiEventHandle();

public void WaitForBlob()
{
  while (true)
  {
    object saved = stateChanged.Current;  // some sentinel value
    if (state == "Blob") break;
    stateChanged.WaitTilNot(saved);  // wait til sentinel value != "current"
  }
}

public void SetBlob()
{
  state = "Blob";
  stateChanged.Change();  // stateChanged.Current becomes a new sentinel object
}
Run Code Online (Sandbox Code Playgroud)

也就是说,任何数量的线程都可以调用WaitForBlob,并且在任何时候(没有竞争条件)SetBlob都可以被另一个线程调用,并且所有等待的线程将立即检测到更改 - 而且重要的是,没有自旋锁或Threading.Sleeps.

现在我想我可以MultiEventHandle相对容易地实现" ".但我的问题是......有更好的方法吗?当然,我认为这是错误的,因为它必须是一个非常常见的用例,但我似乎无法找到一个内置的工具.我担心我可能会在这里发明一个方形轮子.

c# multithreading synchronization

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

使用linq可以使其更具可读性吗?

我正在尝试使用linq,它使我的代码可读 - foreach循环通常是简单的目标.

然而,有一个似乎很简单,但linq形式逃脱了我:

const byte EscapeByte = 0x5C;

List<byte> result = new List<byte>();
foreach (var v in values)
{
    if (v.Escaped)
    {
        result.Add(EscapeByte);
    }
    result.Add(v.DataByte);
}
return result.ToArray();
Run Code Online (Sandbox Code Playgroud)

这可能意味着它最好独自一人..但我很好奇,如果一个老将能够以可读的方式解决它?

c# linq

2
推荐指数
1
解决办法
172
查看次数

确定两个方法是否具有相同的基本定义

我刚刚发现不幸(至少我的应用程序)发现在泛型类中声明的两个方法没有相同的基本定义,在代码中表现最好:

    public static class Test
    {
        private class Generic<T> { public void Method() { } }
        public static void TestBase()
        {
            var x = typeof(Generic<int>).GetMethod("Method");
            var y = typeof(Generic<double>).GetMethod("Method");
            Debug.Assert(x.GetBaseDefinition() == y.GetBaseDefinition()); // fails
        }
    }
Run Code Online (Sandbox Code Playgroud)

x和y.IsGeneric都是false,因此不能使用GetGenericMethodDefinition.

我已经能够想象的,到目前为止唯一的解决办法是比较他们的名字,他们的声明类型相同泛型类型,但在过载的情况下,似乎很脆..

那么..我不认为我在反射库中错过了一个有用的方法,可以告诉我这两个方法是否已在同一个类中首次声明?还是一个解决方法?

编辑:

为了澄清,我想制作一个方法:

    public bool DeclaredInSameClass(MethodInfo a, MethodInfo b);
Run Code Online (Sandbox Code Playgroud)

如果a和b都是在同一个类中首次声明,则返回true.

忽略泛型,这很简单:a.GetBaseDefinition() == y.GetBaseDefinition()但是如何处理泛型类中声明的方法?

.net c# generics reflection

2
推荐指数
1
解决办法
154
查看次数

将ObservableCollection绑定到ItemsControl - 不是听起来那么简单吗?

这很难追查并给我带来了很大的痛苦 - 但似乎ItemsControls并没有像我期望的那样表现.这几乎看起来像WPF中的一个错误 - 但是对WPF来说是新手,我犯错了,这是我的错,而不是他们的错.

要重现它非常简单 - 将an绑定ItemsControl到a ObservableCollection,然后替换集合中的项.这很简单,我无法相信谷歌没有找到数千人遇到同样的问题.

下面简单地将代码绑定一个ItemsControlObservableCollectionBrush.更改刷(点击按钮),你会得到一对夫妇的数据错误为矩形的画笔结合是暂时的DataContextItemsControl(!),而不是新的项目.这种绑定的瞬间崩溃导致我的应用程序每当我替换集合中的(不可变的,常规的CLR对象)项时在调试器中运行时需要花费半秒钟更新 - 我做错了什么?

<Window x:Class="Dummy.Test"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Test" Height="300" Width="300">
    <Grid>
        <ItemsControl ItemsSource="{Binding Foos}">
            <ItemsControl.ItemTemplate>
                <DataTemplate DataType="{x:Type Brush}">
                    <Rectangle Width="20" Height="20" Fill="{Binding}" />
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
        <Button HorizontalAlignment="Center" VerticalAlignment="Bottom" Click="SwitchClick">Switch</Button>
    </Grid>
</Window>
Run Code Online (Sandbox Code Playgroud)
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;

namespace Dummy
{
    public partial class Test : Window
    {
        private readonly ObservableCollection<Brush> foos = new …
Run Code Online (Sandbox Code Playgroud)

c# wpf xaml itemscontrol observablecollection

2
推荐指数
1
解决办法
3923
查看次数

通过广度优先索引递归索引二叉树节点

问题:我需要能够通过索引从未知高度的完美二叉树中递归地检索节点。

由于高度属性未知,似乎唯一有意义的索引形式是广度优先索引(根据标题):

          0
    1           2
3       4   5       6
Run Code Online (Sandbox Code Playgroud)

问题是,在每个节点似乎很难知道要采取哪个方向,以及如何将递归请求中的索引转换为该子节点......或者也许我只是没有思考清楚。

Node Navigate(Index):
Index 0: return this;
Index 1: return Left.Navigate(0);
Index 2: return Right.Navigate(0);
Index 3: return Left.Navigate(1);
Index 4: return Left.Navigate(2);
Index 5: return Right.Navigate(1);
Index 6: return Right.Navigate(2);
...
Index 7: return Left.Navigate(3);
Index 8: return Left.Navigate(4);
Index 9: return Left.Navigate(5);
Index 10: return Left.Navigate(6);
Index 11: return Right.Navigate(3);
Index 12: return Right.Navigate(4);
Index 13: return Right.Navigate(5);
Index 14: return Right.Navigate(6);
Run Code Online (Sandbox Code Playgroud)

模式很清晰 - 但如何以编程方式 - …

algorithm recursion binary-tree

2
推荐指数
1
解决办法
1507
查看次数