我正在处理一个WriteableBitmapC#.我目前正在使用不安全的代码块来直接访问像素WriteableBitmap.BackBuffer./unsafe但是,我宁愿不依赖于选项,所以我正在考虑使用WriteableBitmap.WritePixels.
是否有某种方式在"不安全"版本中有条件地编译,以便在使用/ unsafe编译选项时可以使用它,而无需手动集成到我的项目文件中?
总之,我正在寻找以下内容:
#if UNSAFE
//my unsafe version
#else
//the supposedly safe version goes here
#endif
Run Code Online (Sandbox Code Playgroud)
在运行时检测也很好; 但这意味着我总是需要编译使用 /unsafe,这意味着该库的代码需要的项目文件更新,这是不太方便的.
基本上,我想保留快速版本的重要性,但有一个合理的版本,无论如何都能正常工作.
您是否可以创建实例方法的委托而无需在创建时指定实例?换句话说,你可以创建一个"静态"委托,它应该调用该方法的实例作为它的第一个参数吗?
例如,如何使用反射构造以下委托?
Func<int, string> = i=>i.ToString();
Run Code Online (Sandbox Code Playgroud)
我知道我可以使用methodInfo.Invoke,但速度较慢,并且在调用之前不会检查类型正确性.
当您拥有MethodInfo特定的静态方法时,可以使用构造委托Delegate.CreateDelegate(delegateType, methodInfo),并且静态方法的所有参数都保持空闲.
正如Jon Skeet指出的那样,如果方法在引用类型上是非虚拟的,则可以简单地应用相同的方法来创建实例方法的开放委托.决定在虚拟方法上调用哪个方法很棘手,因此不是那么简单,值类型看起来根本不起作用.
对于价值类型,CreateDelegate展品真的很奇怪:
var func37 = (Func<CultureInfo,string>)(37.ToString);
var toStringMethod = typeof(int).GetMethod("ToString", BindingFlags.Instance | BindingFlags.Public, null, new Type[] {typeof(CultureInfo) }, null);
var func42 = (Func<CultureInfo,string>)Delegate.CreateDelegate(typeof(Func<CultureInfo,string>), 42, toStringMethod,true);
Console.WriteLine( object.ReferenceEquals(func37.Method,func42.Method)); //true
Console.WriteLine(func37.Target);//37
Console.WriteLine(func42.Target);//42
Console.WriteLine(func37(CultureInfo.InvariantCulture));//37
Console.WriteLine(func42(CultureInfo.InvariantCulture));//-201040128... WTF?
Run Code Online (Sandbox Code Playgroud)
如果实例方法属于值类型(这适用于引用类型),则CreateDelegate使用null作为目标对象调用将引发绑定异常.
几年之后的一些后续行动:导致func42(CultureInfo.InvariantCulture);返回"-201040128"而不是"42"在我的示例中的错误绑定目标是可能允许远程代码执行的内存损坏(cve-2010-1898); 这是在2010年ms10-060安全更新中修复的.当前框架正确打印42!这并没有使回答这个问题变得更容易,但解释了这个例子中特别奇怪的行为.
我正在使用boost mt19937实现进行模拟.
模拟需要是可重复的,这意味着以后存储并可能重复使用RNG种子.我正在使用windows crypto api生成种子值,因为我需要种子的外部源,而不是因为任何特殊的随机性保证.任何模拟运行的输出都会有一个包含RNG种子的注释 - 因此种子需要相当短.另一方面,作为模拟分析的一部分,我将比较几次运行 - 但为了确保这些运行实际上是不同的,我需要使用不同的种子 - 所以种子需要足够长避免意外碰撞.
我已经确定64位播种应该足够了; 在大约2 ^ 32次运行后,碰撞的几率将达到50% - 这个概率足够低,以至于它造成的平均误差对我来说可以忽略不计.仅使用32位种子很棘手; 在2 ^ 16次运行后,碰撞的可能性已达到50%; 这对我的口味来说有点太可能了.
不幸的是,增强实现要么是带有完整状态向量的种子 - 这太长,太长 - 或者是一个32位无符号长 - 这并不理想.
如何为超过32位但小于满状态向量的发生器播种?我试着填充矢量或重复种子来填充状态向量,但即使粗略地看一下结果也会显示结果不佳.
考虑以下表达式:
class A {
int x;
public void Method(int y) {
Expression<Func<bool>> expr=() => x == y;
//...
Run Code Online (Sandbox Code Playgroud)
这里,表达式涉及一个自动创建的闭包y,以及(隐式)this类型的引用.两者都将被表示为在表达式树中.给定一个表达式,例如带有此引用和/或闭包的更复杂的表达式,我想要识别特定实际上是"this"或隐式构造的闭包,以便能够从表达式树(ExpressionToCode)重新生成C#.Athis.xMemberExpressionConstantExpressionexprConstantExpression
我使用一些启发式方法构建了一个"解决方案",因为似乎没有一个完美的解决方案.
thislambda总是在ConstantExpressions.this永远不会null.this从结构中捕获引用.这是相当幸运的,因为讲default(StructType).Method()的this.Method(),否则是不可能的,每当this == default(StructType).this或闭包<并注释CompilerGeneratedAttribute
DisplayClass,匿名类型包含AnonymousTypethis必须是正常类型:不是CompilerGenerated也不是以<以上启发式方法是否足以区分实常数this,闭包和匿名类型?即有这些启发式失败的情况,或者我错过了什么?这可能会在未来的.NET版本中破裂吗?
编辑: …
对于我正在编写的一些常规辅助方法,我希望能够在该值是其类型的默认值时调用特殊处理.对于参考类型,这很容易 - 默认值是null.我不能使用泛型类型参数,虽然我可以解决这个问题.
我可以这样做:
public bool DetectPossiblyUninitializedValue(object val) {
return val== null ||
val.GetType().IsValueType
&& Equals(val, Activator.CreateInstance(val.GetType());
}
Run Code Online (Sandbox Code Playgroud)
这就是我现在正在使用的,但这取决于它的实现Equals.那很好,但不理想.特别是,某些实现可能会覆盖Equals以支持正常方案中更多可用的语义.在这里将默认值视为特殊情况实际上并不罕见,因为由于默认初始化,它在.NET中是不可避免的.
但是,在这种情况下,我只想知道对象是否已经初始化,因此我不想要任何自定义相等或其他.基本上,我想知道结构占用的内存区域是否填充为零,因为初始化后VM保证,而不是更多.从某种意义上说,我正在寻找类似于ReferenceEquals结构的东西:无视底层对象自身实现的比较.
如何在不使用的情况下比较原始结构值Equals?我可以比较原始结构值吗?
编辑:我正在使用它来连接表示特定于域的概念的类+结构,这些概念由表示各种业务规则的基本上任意代码连接到GUI.一些旧的代码基本上处理可能嵌套的字符串到任意对象的字典,因此需要一堆未经检查的强制转换或者dynamic; 创建这些是容易出错的.因此能够相对直接地处理类型化对象很好.另一方面,GUI和包装代码以不同方式处理可能未初始化的值是有用的; 虽然逐个案例,逐个类型的解决方案是可能的,这是很多代码; 合理的默认值很有用.我真正想要的是一种自动生成一种类型的方法,该类型与另一种类型相同,但所有属性/公共字段都扩展为包含"未初始化"值,但这不是一个期望的现实特征 - 相比之下,在动态世界中这将是虽然在其他地方没有类型安全,但是可以轻易实现......
答案: Mehrdad发布了一个关于如何直接访问结构的答案; 我添加了一个实现,用于检测可能未初始化的值.
有时会出现例外情况.当他们这样做时,他们会被记录下来并进行分析.该日志显然包含堆栈跟踪和其他全局信息,但通常缺少关键的上下文.我想用这些额外的信息来注释一个例外以便于事后调试.
try{...}catch{... throw;}因为它被视为捕获异常并且使调试更难(在开发期间我希望应用程序停止并且调试器在抛出原始异常时做出反应,而不是在最外面的未捕获异常时) .第一次机会异常处理程序不是一种解决方法,因为不幸的是,有太多误报.有没有办法以不捕获异常的方式在异常中存储关键的上下文(例如正在处理的文件名或其他)?
我有这样的代码:
IEnumerable<string?> items = new [] { "test", null, "this" };
var nonNullItems = items.Where(item => item != null); //inferred as IEnumerable<string?>
var lengths = nonNullItems.Select(item => item.Length); //nullability warning here
Console.WriteLine(lengths.Max());
Run Code Online (Sandbox Code Playgroud)
我如何以一种方便的方式编写此代码,例如:
nonNullItems推断为IEnumerable<string>。item!(因为我想从编译器的健全性检查中受益,而不是依靠我成为无错误的编码器)我知道这种解决方案,它利用了C#8.0编译器中的流敏感型输入,但是它不是很漂亮,主要是因为它又长又嘈杂:
var notNullItems = items.SelectMany(item =>
item != null ? new[] { item } : Array.Empty<string>())
);
Run Code Online (Sandbox Code Playgroud)
有更好的选择吗?
我今天在JavaScript中使用正则表达式时遇到了一种奇怪的行为(Windows Vista上的Firefox 3).
var str = "format_%A";
var format = /(?:^|\s)format_(.*?)(?:\s|$)/.exec(str);
console.log(format); // ["format_%A", "%A"]
console.log(format[0]); // "format_undefined"
console.log(format[1]); // Undefined
Run Code Online (Sandbox Code Playgroud)
正则表达式没有错.如您所见,它与第一次console.log调用中的正确部分相匹配.
Internet Explorer 7和Chrome都按预期运行:format[1]返回"%A" (好吧,Internet Explorer 7做正确的事情有点出乎意料......)
这是Firefox中的一个错误,还是我不知道的一些"功能"?
这是一个简单的程序来查找最常出现在数组中的元素:
#include <cstdlib>
#include <iostream>
#include <vector>
using namespace std;
int main(int argc, char *argv[]) {
int a[] = {1,2,3,4,4,4,5};
int n = sizeof(a) / sizeof(int);
int max = 0;
int result = 0;
int *b = new int[n];
for (int i = 0; i < n; i++) {
b[a[i]] = (b[a[i]] || 0) + 1;
if (b[a[i]] > max) {
max = b[a[i]];
result = a[i];
}
}
cout << result << endl;
system("PAUSE");
return EXIT_SUCCESS;
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用; 它打印 …