我有以下程序,它从两个静态方法构造一个本地Func.但奇怪的是,当我分析程序时,它分配了近百万个Func对象.为什么调用Func对象也在创建Func实例?
public static class Utils
{
public static bool ComparerFunc(long thisTicks, long thatTicks)
{
return thisTicks < thatTicks;
}
public static int Foo(Guid[] guids, Func<long, long, bool> comparerFunc)
{
bool a = comparerFunc(1, 2);
return 0;
}
}
class Program
{
static void Main(string[] args)
{
Func<Guid[], int> func = x => Utils.Foo(x, Utils.ComparerFunc);
var guids = new Guid[10];
for (int i = 0; i < 1000000; i++)
{
int a = func(guids);
}
}
}
Run Code Online (Sandbox Code Playgroud) 当使用ValueTuple动态对象时,我收到了这个奇怪的CS8133错误.我传递动态对象作为输入并将ValueTuple作为输出.他们为什么互相影响.
public static (string, string) foo(dynamic input)
{
return ("", "");
}
public void foo_test()
{
dynamic input = new { a = "", b = "" };
(string v1, string v2) = foo(new { a = "", b = "" }); //compiles fine
(string v3, string v4) = foo(input); //CS8133 Cannot deconstruct dynamic objects
var result = foo(input); //compiles fine
}
Run Code Online (Sandbox Code Playgroud)
编辑:错误消息是: CS8133 Cannot deconstruct dynamic objects
IDisisposable模式实现起来很昂贵.在开始实际处理资源之前,我已经计算了17行代码.
Eric Lippert最近撰写了一篇博客文章,提出了一个有趣的观点:任何时候终结者都会运行,这是一个错误.我觉得这很有道理.如果始终遵循IDisposable模式,则应始终抑制Finalizer.它永远不会有机会跑.如果我们接受终结器运行是一个错误,那么有一个指导方针迫使开发人员从以下抽象类派生并禁止直接实现IDisposable接口.
public abstract class AbstractDisaposableBase: IDisposable
{
~AbstractDisaposableBase()
{
ReportObjectLeak();
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected abstract void Dispose(bool disposing);
[Conditional("DEBUG")]
private void ReportObjectLeak()
{
//Debug.Assert(false, "leaked instance");
//throw new Exception("leaked instance");
}
}
Run Code Online (Sandbox Code Playgroud)
好处很明显:
class MyClass1 : DisablableBase
{
protected override void Dispose(bool disposing)
{
//dispose both managed and unmamaged resources as though disposing==true
}
}
Run Code Online (Sandbox Code Playgroud)
没有处置对象报告
始终遵循一次性模式
但是,这样的指南有什么问题吗?
一个可能的问题是所有一次性物体都将定义一个终结器.但由于终结器总是受到抑制,因此不应该有任何性能损失.
你的想法是什么?
除了行为,我对以下的linq感到非常惊讶,有人能解释为什么吗?我已经列出了我对linq的工作方式的理解/假设。至少其中之一是错误的。
public class Obj {
public string Name;
public Obj(string name)
{
this.Name = name;
}
}
class Program
{
public static void Main(string[] args)
{
var list1 = "a,b"
.Split(',')
.Select(x => new Obj(x));
var list2 = list1.Where(x => x.Name == "b");
var list3 = list1.Except(list2).ToList();
}
}
Run Code Online (Sandbox Code Playgroud)
但是显然不是这样。在调试器中检查时,list3包含{Obj('a'),Obj('b')},并且这些对象不是list1包含的引用的等同对象。和Obj构造函数被调用4次。
linq不应该Where和Excet方法只是将对象引用从一个IEnumerable复制到另一个IEnumerable吗?创建对象副本的对象是谁?
c# ×4
architecture ×1
c#-7.0 ×1
closures ×1
delegates ×1
disposable ×1
dynamic ×1
finalizer ×1
linq ×1
performance ×1
roslyn ×1