小编Rau*_*otz的帖子

C#(.NET)设计缺陷

C#或.NET Framework中一些最大的设计缺陷是什么?

示例:没有非可空字符串类型,您必须在从IDataReader获取值时检查DBNull.

.net c#

85
推荐指数
21
解决办法
1万
查看次数

使用常量值进行直接数组初始化

每当你在C#中分配一个新数组时

new T[length]
Run Code Online (Sandbox Code Playgroud)

数组条目设置为默认值T. null对于T作为引用类型的情况或默认构造函数的结果T,if T是值类型.

在我的情况下,我想初始化一个Int32值为-1 的数组:

var myArray = new int[100];
for (int i=0; i<myArray.Length; i++) { myArray[i] = -1; }
Run Code Online (Sandbox Code Playgroud)

内存保留用于阵列操作后,在CLR循环通过新分配的内存,并设置所有条目为默认(INT)= 0.在那之后,我的代码将所有条目为-1.

这使初始化变得多余.是否JIT进行检测,并忽略了初始化为0,如果没有,有没有办法直接与自定义值初始化存储器的一部分?

参照C#数组初始化-与非默认值,使用Enumerable.Repeat(value, length).ToArray()没有选项,因为Enumerable.ToArray以后分配一个新的数组,并复制的值到它.

c# arrays initialization constants

48
推荐指数
3
解决办法
5万
查看次数

适当的C#中的Currying

给定一个DoSomething采用(无参数)函数的方法并以某种方式处理它.有没有更好的方法为参数的函数创建"重载"而不是下面的代码片段?

public static TResult DoSomething<TResult>(Func<TResult> func)
{
    //call func() and do something else
}

public static TResult DoSomething<T0, TResult>(
    Func<T0, TResult> func,
    T0 arg0)
{
    return DoSomething(() => func(arg0));
}

public static TResult DoSomething<T0, T1, TResult>(
    Func<T0, T1, TResult> func,
    T0 arg0, T1 arg1)
{
    return DoSomething(arg => func(arg, arg1), arg0);
}

public static TResult DoSomething<T0, T1, T2, TResult>(
    Func<T0, T1, T2, TResult> func,
    T0 arg0, T1 arg1, T2 arg2)
{
    return DoSomething(arg => func(arg, arg1, arg2), arg0); …
Run Code Online (Sandbox Code Playgroud)

c# lambda currying

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

为什么从C#调用Python lambda表达式不是线程安全的?

我在IronPython中定义了一个无副作用(纯)lambda表达式,并将其分配给C#委托.当从多个线程同时调用委托时,我得到类型为AccessViolationException,NullReferenceExceptionFatalEngineExecutionError的异常.

错误的发生是非确定性的,并且它主要需要数百万次迭代来激发它,这对我说"竞争条件".我怎么能避免呢?

只有在使用x64(x86不崩溃)并且在调试器之外运行进程时才会引发异常.测试系统是Windows 7,.NET Framework 4.0和IronPython 2.7.1上的Core I7(8个线程).

这是产生错误的最小代码:

var engine = Python.CreateEngine();

double a = 1.0;
double b = 2.0;

while (true)
{
    Func<double, double, double> calculate = engine.Execute("lambda a,b : a+b");

    System.Threading.Tasks.Parallel.For(0, 1000, _ =>
    {
         for (int i = 0; i < 1000; i++) { calculate(a,b); }
    });

    Console.Write(".");   
}
Run Code Online (Sandbox Code Playgroud)

错误信息:

检测到FatalExecutionEngineError

消息:运行时遇到致命错误.错误的地址是0xf807829e,位于线程0x3da0上.错误代码是0xc0000005.此错误可能是CLR中的错误,也可能是用户代码的不安全或不可验证部分中的错误.此错误的常见来源包括COM-interop或PInvoke的用户编组错误,这可能会破坏堆栈.

更新:即使引擎声明为线程本地,它会在一段时间后崩溃:

var calculate = new ThreadLocal<Func<double, double, double>>(() => Python.CreateEngine().Execute("lambda a,b : a+b"));
Run Code Online (Sandbox Code Playgroud)

c# lambda ironpython thread-safety

28
推荐指数
1
解决办法
1032
查看次数

.NET进程可以分配的最大内存

垃圾回收器可以为.NET进程分配的最大内存是多少?当我编译为x64时,Process.GetCurrentProcess.MaxWorkingSet返回大约1,4GB,但是当我编译到AnyCPU(x64)时,返回相同的数字.对于x64,它应该更像是任务管理器中显示的"限制"值.如何在所有情况下获得超出OutOfMemory-Exceptions的正确数字?

一些示例应该返回的方法:

1)机器配置:x64-Windows,4GB物理内存,4GB页面文件
- 作为64位进程:8GB
-As 32位进程:1.4GB

2)机器配置:x64-Windows,1GB物理内存,2GB页面文件
- 作为64位进程:3GB
-As 32位进程:1.4GB

3)机器配置:x32-Windows,4GB物理内存,4GB页面文件
- 作为64位进程:不会发生
- 作为32位进程:1.4GB

4)机器配置:x32-Windows,512MB物理内存,512MB页面文件
- 作为64位进程:不会发生
- 作为32位进程:1.0GB

.net memory-management

26
推荐指数
2
解决办法
2万
查看次数

WeakReference是否可以提供良好的缓存?

我有一个缓存,使用WeakReferences缓存对象,以便在内存压力的情况下自动从缓存中删除它们.我的问题是缓存的对象在存储在缓存中后很快就会被收集.缓存在64位应用程序中运行,尽管仍然有超过4gig的内存可用,但所有缓存的对象都被收集(它们通常在那时存储在G2堆中).过程资源管理器显示没有手动引发的垃圾收集.

我可以采用哪些方法让对象更长寿?

.net c# caching garbage-collection weak-references

14
推荐指数
4
解决办法
8831
查看次数

抛出异常时,使用Lazy <T>的StackOverflowException

一个非常简单的示例应用程序(.NET 4.6.2)在12737的递归深度处产生StackOverflowException ,如果最内部函数调用抛出异常(预期和正常),则递减深度为10243.

如果我使用a Lazy<T>来短暂保存中间结果,则StackOverflowException已经发生在2207的递归深度,如果没有抛出异常并且在递归深度为105,则抛出异常.

注意:如果编译为x64,则深度为105的StackOverflowException 仅可观察.使用x86(32位),效果首先发生在4272的深度.Mono(就像在https://repl.it上使用的那样)可以毫无问题地工作到74200的深度.

StackOverflowException不会在深度递归中发生,而是在升级回主程序时发生.finally块被深度处理,然后程序死掉:

Exception System.InvalidOperationException at 105
Finally at 105
...
Exception System.InvalidOperationException at 55
Finally at 55
Exception System.InvalidOperationException at 54
Finally at 54
Process is terminated due to StackOverflowException.
Run Code Online (Sandbox Code Playgroud)

或者在调试器中:

The program '[xxxxx] Test.vshost.exe' has exited with code -2147023895 (0x800703e9).
Run Code Online (Sandbox Code Playgroud)

谁能解释一下这个?

public class Program
{
    private class Test
    {
        private int maxDepth;

        private int …
Run Code Online (Sandbox Code Playgroud)

c#

9
推荐指数
1
解决办法
512
查看次数

C#lambda表达式和惰性求值

lambda表达式的一个优点是,只有在需要结果时才需要计算函数.

在下面(简单)示例中,仅在编写器存在时才评估文本函数:

public static void PrintLine(Func<string> text, TextWriter writer)
{
    if (writer != null)
    {
        writer.WriteLine(text());
    }
}
Run Code Online (Sandbox Code Playgroud)

不幸的是,这使得使用代码有点难看.你不能用常量或变量来调用它

PrintLine("Some text", Console.Out);
Run Code Online (Sandbox Code Playgroud)

并且必须这样称呼它:

PrintLine(() => "Some text", Console.Out);
Run Code Online (Sandbox Code Playgroud)

编译器无法从传递的常量"推断"无参数函数.有没有计划在未来的C#版本中改进这一点,还是我错过了什么?

更新:

我自己发现了一个肮脏的黑客:

    public class F<T>
    {
       private readonly T value;
       private readonly Func<T> func;

       public F(T value) { this.value = value; }
       public F(Func<T> func) {this.func = func; }

       public static implicit operator F<T>(T value)
       {
            return new F<T>(value);
       }

       public static implicit operator F<T>(Func<T> func)
       {
           return new F<T>(func);
       } …
Run Code Online (Sandbox Code Playgroud)

lambda lazy-evaluation c#-3.0

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

预加载装配

在工作中,我们使用DevExpress作为用户界面.第一次打开使用DevExpress控件的表单会有很长的停顿时间(某些客户端有时会持续15-20秒).在Visual Studio中,我可以看到在该阶段正在加载大量的程序集.有没有办法在生成的线程的后台将该程序集预加载到AppDomain中,例如在登录屏幕弹出之前?

.net c# optimization assemblies

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

类型可以同时是引用类型和值类型吗?

如果没有,并且引用类型和值类型的集合是互斥的,为什么不编译:

public static void Do<T>(T obj) where T : struct { }
public static void Do<T>(T obj) where T : class { }
Run Code Online (Sandbox Code Playgroud)

编译器声明:"Type已经定义了一个名为'Do'的成员,它具有相同的参数类型."但是T和T在这里不一样.一个是约束结构,另一个是类的约束.对函数的调用应该始终是可解析的.有反例吗?

c# type-systems

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