我收集了一些角落案例和脑筋急转弯,并且总是希望听到更多.该页面仅涵盖C#语言位和bobs,但我也发现核心.NET的东西也很有趣.例如,这是一个不在页面上,但我觉得不可思议的:
string x = new string(new char[0]);
string y = new string(new char[0]);
Console.WriteLine(object.ReferenceEquals(x, y));
Run Code Online (Sandbox Code Playgroud)
我希望打印False - 毕竟,"new"(带引用类型)总是会创建一个新对象,不是吗?C#和CLI的规范都表明它应该.好吧,不是在这种特殊情况下.它打印True,并在我测试过的每个版本的框架上完成.(我没有在Mono上尝试过,诚然......)
需要明确的是,这只是我正在寻找的那种事情的一个例子 - 我并不是特别想要讨论这种奇怪的事情.(它与正常的字符串实习不同;特别是,当调用构造函数时,通常不会发生字符串实习.)我真的要求类似的奇怪行为.
还有其他宝石潜伏在那里吗?
我的问题与此问题有些相关:泛型约束如何阻止使用隐式实现的接口对值类型进行装箱?,但不同,因为它不需要约束来执行此操作,因为它根本不是通用的.
我有代码
interface I { void F(); }
struct C : I { void I.F() {} }
static class P {
static void Main()
{
C x;
((I)x).F();
}
}
Run Code Online (Sandbox Code Playgroud)
主要方法编译如下:
IL_0000: ldloc.0
IL_0001: box C
IL_0006: callvirt instance void I::F()
IL_000b: ret
Run Code Online (Sandbox Code Playgroud)
为什么不编译到这个?
IL_0000: ldloca.s V_0
IL_0002: call instance void C::I.F()
IL_0007: ret
Run Code Online (Sandbox Code Playgroud)
我明白为什么你需要一个方法表来进行虚拟调用,但在这种情况下你不需要进行虚拟调用.如果接口正常实现,则不进行虚拟呼叫.
还相关:为什么显式接口实现是私有的? - 关于这个问题的现有答案没有充分解释为什么这些方法在元数据中被标记为私有(而不是仅仅具有不可用的名称).但即使这样也没有完全解释为什么它是盒装的,因为从C里面调用时它仍然是盒子.
Func<...>在使用继承和泛型时,我一直无法理解在整个代码中使用的性能特征- 这是我发现自己一直使用的组合.
让我从一个最小的测试用例开始,这样我们都知道我们在谈论什么,然后我会发布结果,然后我将解释我期望的内容以及为什么......
最小的测试用例
public class GenericsTest2 : GenericsTest<int>
{
static void Main(string[] args)
{
GenericsTest2 at = new GenericsTest2();
at.test(at.func);
at.test(at.Check);
at.test(at.func2);
at.test(at.Check2);
at.test((a) => a.Equals(default(int)));
Console.ReadLine();
}
public GenericsTest2()
{
func = func2 = (a) => Check(a);
}
protected Func<int, bool> func2;
public bool Check2(int value)
{
return value.Equals(default(int));
}
public void test(Func<int, bool> func)
{
using (Stopwatch sw = new Stopwatch((ts) => { Console.WriteLine("Took {0:0.00}s", ts.TotalSeconds); }))
{
for (int i = 0; i < 100000000; …Run Code Online (Sandbox Code Playgroud) 在将属性static/shared作为实例属性之前,可能是任何锁定机制时,性能是否存在差异?
HttpCache中有一个使用频繁的对象,可以通过页面实例(Service.aspx)中的属性访问.现在我想知道是否更好地使它静态,因为无论如何HttpCache在应用程序中共享.
我决定使其静态的主要原因是因为它更容易引用(Service.dsRMAvs. ((Service)Page).dsRMA).
我知道静态功能和线程安全可能出现的问题.
感谢您的时间.
之前:
C#
public ERPModel.dsRMA dsRMA {
get {
if (Cache("DS_RMA") == null) {
Cache("DS_RMA") = new ERPModel.dsRMA();
}
return (ERPModel.dsRMA)Cache("DS_RMA");
}
}
Run Code Online (Sandbox Code Playgroud)
VB
Public ReadOnly Property dsRMA() As ERPModel.dsRMA
Get
If Cache("DS_RMA") Is Nothing Then
Cache("DS_RMA") = New ERPModel.dsRMA
End If
Return DirectCast(Cache("DS_RMA"), ERPModel.dsRMA)
End Get
End Property
Run Code Online (Sandbox Code Playgroud)
之后:
C#
public static ERPModel.dsRMA dsRMA {
get {
if (HttpContext.Current.Cache("DS_RMA") == null) {
HttpContext.Current.Cache("DS_RMA") = new ERPModel.dsRMA();
}
return (ERPModel.dsRMA)HttpContext.Current.Cache("DS_RMA"); …Run Code Online (Sandbox Code Playgroud) 我看到当我调用类的实例方法时,C#编译器会发出callvirt调用该方法的
指令,为什么会这样呢?
这是否意味着所有实例方法都被virtual methods编译器视为什么,这是什么谜?
c# ×6
.net ×5
cil ×2
performance ×2
asp.net ×1
boxing ×1
generics ×1
inheritance ×1
interface ×1
null ×1
reflection ×1
vb.net ×1