我正试图坚持WeakKeyedDictionary<,>C#的真实细节......但我遇到了困难.
我意识到这是一个非常重要的任务,但似乎无法声明a WeakKeyedKeyValuePair<,>(如果密钥可达,GC只跟随值引用)使得它看起来似乎不可能.
我看到两个主要问题:
到目前为止,我所看到的每个实现都没有在收集密钥后修剪值.考虑一下 - 使用这样一个字典的主要原因之一是防止这些值被保留(不仅仅是键!),因为它们无法访问,但在这里它们被强引用指向.
是的,在词典中添加/删除足够多,它们最终会被替换,但是如果你不这样做呢?
如果没有一个假设WeakKeyedKeyValuePair<,>(或告诉GC到的另一种方法只标出值,如果关键是可达)是指它的键永远不会被收集的任何值.存储任意值时,这是一个问题.
问题1可以在一个相当不理想/ hackish的方式来解决:使用GC通知等待一个完整的GC完成,然后沿着去修剪字典在另一个线程.这个我半熟的.
但问题2让我难过.我意识到这很容易被"所以不要这样做"所抵消,但我想知道 - 这个问题甚至可以解决吗?
如果我想创建一个使用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(或者根本没有运行时编译)中相当容易地解决,但不幸的是,这是一个更大的表达式构建过程的一部分...所以我真的希望这不是一个限制,因为完全重写将不仅仅是一种痛苦.
精简版:
我希望能够在a中定义汇编程序宏,macros.S并asm()在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预处理器的使用,可以做些什么呢?
这可能是众所周知和讨论的,但令我惊讶的是,我今天发现你可以在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) 我们希望为我们的客户提供基于我们的客户定制exes的能力.
即,基本上能够使用嵌入在其中的不同xml配置文件制作exe的副本."将它包含在安装中"不是一个选项 - 我们希望这看起来好像是为我们客户的客户定制的.
我目前正在考虑在运行时编写一个dll,包括资源(使用AssemblyBuilder),然后调用ILMerge将其嵌入到最终的exe中,但这比我想要的稍微强一些.
所以这是一个很高的问题,但也许值得问一下:是否有一个.NET库允许修改.NET exe的资源,这可以避免整个"dll持有ILMerge嵌入的资源"位?
或者,是否有更好的方法可以达到既定目标?
(我认为)我想要的是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相对容易地实现" ".但我的问题是......有更好的方法吗?当然,我认为这是错误的,因为它必须是一个非常常见的用例,但我似乎无法找到一个内置的工具.我担心我可能会在这里发明一个方形轮子.
我正在尝试使用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)
这可能意味着它最好独自一人..但我很好奇,如果一个老将能够以可读的方式解决它?
我刚刚发现不幸(至少我的应用程序)发现在泛型类中声明的两个方法没有相同的基本定义,在代码中表现最好:
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()但是如何处理泛型类中声明的方法?
这很难追查并给我带来了很大的痛苦 - 但似乎ItemsControls并没有像我期望的那样表现.这几乎看起来像WPF中的一个错误 - 但是对WPF来说是新手,我犯错了,这是我的错,而不是他们的错.
要重现它非常简单 - 将an绑定ItemsControl到a ObservableCollection,然后替换集合中的项.这很简单,我无法相信谷歌没有找到数千人遇到同样的问题.
下面简单地将代码绑定一个ItemsControl到ObservableCollection的Brush.更改刷(点击按钮),你会得到一对夫妇的数据错误为矩形的画笔结合是暂时的DataContext的ItemsControl(!),而不是新的项目.这种绑定的瞬间崩溃导致我的应用程序每当我替换集合中的(不可变的,常规的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) 问题:我需要能够通过索引从未知高度的完美二叉树中递归地检索节点。
由于高度属性未知,似乎唯一有意义的索引形式是广度优先索引(根据标题):
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)
模式很清晰 - 但如何以编程方式 - …
c# ×8
.net ×3
algorithm ×1
assembly ×1
binary-tree ×1
c ×1
dictionary ×1
exe ×1
gcc ×1
generics ×1
itemscontrol ×1
linq ×1
nullable ×1
recursion ×1
reflection ×1
wpf ×1
xaml ×1