在C#中,是否有任何好的理由(除了更好的错误消息)将参数空值检查添加到null不是有效值的每个函数?显然,使用s的代码无论如何都会抛出异常.而这样的检查使代码变得更慢,更难维护.
void f(SomeType s)
{
if (s == null)
{
throw new ArgumentNullException("s cannot be null.");
}
// Use s
}
Run Code Online (Sandbox Code Playgroud) 在我的项目中,我正在运行一个外部工具来更新一些二进制文件.这些文件作为"内容"包含在项目中.
此工具设置为在C#项目属性中的"预构建事件"期间运行.不幸的是,只有在项目过期时才会执行此事件,这不是我需要的.
我通过在我的项目中总是使用"rebuild"而不是"build"来解决这个问题,但这很乏味且很慢.
无论项目是否是最新的,我都需要始终执行此工具.实际上,甚至在MSBuild确定项目是否是最新的之前,因为该工具修改了项目中包含的一些文件,因此影响了最新的检查结果.
有没有正确的方法呢?
以下 C# 程序以静默方式隐式调用显式小数到长整型转换运算符,从而丢失精度。
我不明白为什么会发生这种情况。据我了解,在 C# 中,显式运算符不应由语言隐式调用。特别是在这种情况下,静默显式转换正在失去精度(1.1M => 1L)。
这种奇怪的行为实际上导致了我的程序中的错误。
这是简化的代码:
// Custom number class
struct Num
{
long Raw;
public static implicit operator Num(long v) => new Num { Raw = v };
}
class Program
{
static void Main()
{
decimal d = 1.1m;
// The following line implicitly converts d to long (silently losing precision),
// then calls Num.op_Implicit(long)
Num num = (Num)d; // <=== should not compile???
}
}
Run Code Online (Sandbox Code Playgroud)
这是生成的 IL。您可以看到它System.Decimal::op_Explicit
被调用了,即使它从未被要求过。 …
我想修改一个结构的字段,该结构在一个数组内,而不必设置整个结构.在下面的示例中,我想在数组中设置元素543的一个字段.我不想复制整个元素(因为复制MassiveStruct会损害性能).
class P
{
struct S
{
public int a;
public MassiveStruct b;
}
void f(ref S s)
{
s.a = 3;
}
public static void Main()
{
S[] s = new S[1000];
f(ref s[543]); // Error: An object reference is required for the non-static field, method, or property
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在C#中做到这一点?或者我总是要从数组中复制整个结构,修改副本,然后将修改后的副本放回到数组中.
请考虑以下代码模式:
// Each foo keeps a reference to its manager
class Foo
{
private FooManager m_manager;
}
// Manager keeps a list of all foos
class FooManager
{
private List<Foo> m_foos;
}
Run Code Online (Sandbox Code Playgroud)
问题:没有办法创建一个新的Foo并更新FooManager中的m_foos列表和新Foo实例中的m_manager引用,而不公开公开一些私有(并冒着某人用实际Foos取消列表的风险).
例如,可以在Foo中实现构造函数Foo(FooManager manager).它可以设置m_manager引用,但无法访问m_foos列表.或者您可以在管理器中实现CreateFoo()方法.它可以访问m_foos列表,但无法在Foo中设置m_manager.
在C++中,显然会声明FooManager是Foo的朋友来表达设计意图,但这在C#中是不可能的.我也知道我可以让Foo成为FooManager的内部类以获得访问权限,但这也不是一个解决方案(如果Foo可以属于多个经理类怎么办?)
顺便说一句.我知道.NET中的"内部"访问,但它要求Foo和FooManager独立存在于一个单独的程序集中,这是不可接受的.
没有公开私有东西的任何变通办法吗?
Python中的纪元开始时间是否独立于平台(即始终是1970年1月1日)?
还是依赖平台?
我想在运行Python的各种机器上序列化日期时间(具有第二精度),并且能够在不同平台上读取它们,可能还使用不同的编程语言(比Python).序列化纪元时间是个好主意吗?
我正在使用SciTech的.NET Memory Profiler来降低程序的内存分配率并减少垃圾收集的频率.
令人惊讶的是,根据分析器,最大量的分配似乎来自GCHandle.Alloc调用我正在做的将现有的.NET数组编组为本机OpenGL.
我的理解是调用GCHandle.Alloc不分配内存,它只引导托管堆上的现有内存?
我错了还是导演错了?
我注意到C#jitter产生的代码比C++编译器慢得多,即使没有使用"托管开销"构造(例如带有检查索引的数组).
为了量化它,我计算了以下简单的循环:
public static int count = 1000000000;
public static int Main()
{
int j = 0;
for (int i = 0; i < count; ++i)
{
j += (i % 2 == 0) ? ((i + 7) >> 3) : (i * 7);
}
return j;
}
Run Code Online (Sandbox Code Playgroud)
这个循环需要3.88秒来执行(用/ o编译).使用VC 2010(-O2)编译的等效循环需要2.95秒.
为了验证实际生成了劣质代码,我比较了机器代码:从VC编译器创建了一个列表(/ FAs),并将一个调试器附加到C#程序(在循环完成之后).
的确,C++版本正在使用一些聪明的技巧.例如,为了避免昂贵的乘法乘以7,有一个单独的寄存器,每个循环计数增加7.C#版本每次都进行乘法(imul).还有其他差异.
据我所知,C#jitter在运行时编译代码的时间远远少于构建时的VC.但是,例如Java抖动是动态优化常用方法.C#似乎没有这样做.
我的问题是:是否有计划在未来的框架版本中改进C#jitter?
有没有人知道C#中的探查器库我可以嵌入我的源代码中进行基于样本的分析?即定期获取指令指针位置,将其存储在内存中并允许将其保存到文件中并稍后进行分析,可能是某些桌面应用程序?
我知道有很多传统的探查器应用程序(如JetBrains,Ants等),但我想描述一个在非桌面平台上运行的C#程序,其中不能使用这些探查器.我希望我的应用程序自己进行采样,而不是外部探查器.
在C#中,我正在使用大型值类型数组.我希望能够转换兼容值类型的数组,例如:
struct Color
{
public byte R, G, B, A;
}
Color[] bitmap1 = ...;
uint[] bitmap2 = MagicCast(bitmap1);
Run Code Online (Sandbox Code Playgroud)
我希望bitmap2与bitmap1共享内存(它们具有相同的位表示).我不想复制.
有办法吗?