小编Vin*_*nce的帖子

为什么Single()不会在找到多个元素时直接返回?

我在Enumerable.Single方法中发现(大致)这个代码,同时用一些反编译器检查它:

foreach (TSource current in source)
{
    if (predicate(current))
    {
        result = current;
        num += 1L;
    }
}

if (num > 1L)
{
     throw Error.MoreThanOneMatch();
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它会在投掷之前循环遍历所有项目.它为什么不打破num > 1

.net c# linq internals

18
推荐指数
1
解决办法
366
查看次数

除了泛型类之外,还有其他方法可以调用结构的接口方法而不需要装箱吗?

请参阅代码段

public interface I0
{
    void f0();
}
public struct S0:I0
{
    void I0.f0()
    {

    }
}
public class A<E> where E :I0
{
    public E e;
    public void call()
    {
        e.f0();
    }
}
Run Code Online (Sandbox Code Playgroud)

这是用于调用的IL代码()

.maxstack 8
L_0000: ldarg.0 
L_0001: ldflda !0 Temp.A`1<!E>::e
L_0006: constrained !E
L_000c: callvirt instance void Temp.I0::f0()
L_0011: ret 
Run Code Online (Sandbox Code Playgroud)

参见约束的参考

约束前缀也可用于在值类型上调用接口方法,因为可以使用MethodImpl更改实现接口方法的值类型方法.如果未使用约束前缀,则强制编译器在编译时选择要绑定到哪个值类型的方法.使用约束前缀允许MSIL在运行时绑定到实现接口方法的方法,而不是在编译时绑定.

这意味着它将调用一个包含接口方法代码f0的方法而不用装箱结构.

在C#中,如上所述GenericClass是否存在任何其他方式没有装箱的caling接口方法?

c# il

11
推荐指数
1
解决办法
1295
查看次数

IntPtr允许从ulong到long的隐式转换

class A
{
    public static explicit operator A(long mm)
    {
        return null;
    }
}
UInt64 ul = UInt64.MaxValue;
IntPtr ptr = (IntPtr)ul;//no error
A a = (A)ul;//Cannot convert type 'ulong' to 'A'
Run Code Online (Sandbox Code Playgroud)

为什么IntPtr允许这种行为?

以下是IL代码:

.entrypoint
.maxstack 1
.locals init (
    [0] uint64 ul,
    [1] native int ptr)
L_0000: nop 
L_0001: ldc.i4.m1 
L_0002: conv.i8 
L_0003: stloc.0 
L_0004: ldloc.0 
L_0005: call native int [mscorlib]System.IntPtr::op_Explicit(int64)
L_000a: stloc.1 
L_000b: ret 
Run Code Online (Sandbox Code Playgroud)

c# intptr

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

在x86上如果[mem]不是32位对齐,可以"锁定inc [mem]"仍然可以正常工作吗?

在x86上,如果mem是32位对齐的,则mov操作保证是原子的.

如果[mem]不是32位对齐,那么lock inc [mem]sill工作正常吗?

工作正常:提供原子性而不是获得部分价值.

x86 assembly multithreading multiprocessing

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

为什么GroupJoin没有留下外连接?

GroupJoin方法在关系数据库术语中没有直接等价,但它实现了内连接和左外连接的超集.左外连接是返回第一个(左)数据源的每个元素的连接,即使它在其他数据源中没有相关元素也是如此.

我认为GroupJoin相当于左连接.因为外部的所有元素都将返回内部匹配项的集合.如果在inner中找不到匹配的项,则空集合将与外部元素配对.

但为什么msdn会这么说呢?

我已阅读GroupJoin和Join的源代码.MarcinJuraszek提供了一个例子.但我认为我们可以使用以下代码.

Users.GroupJoin(Cars,user=>id,Car=>userId,(user,cars)=>
if(cars.count==0)
{
//John -- NULL
}
else
{
//Ted  -- [ 2, 3 ]
}
return result;
);
Run Code Online (Sandbox Code Playgroud)

GroupJoin的原始逻辑:

Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, comparer);
foreach (TOuter current in outer)
{
    yield return resultSelector(current, lookup[outerKeySelector(current)]);
}
Run Code Online (Sandbox Code Playgroud)

我们也可以重写一个LeftJoin:

Lookup<TKey, TInner> lookup = Lookup<TKey, TInner>.CreateForJoin(inner, innerKeySelector, 
foreach (TOuter current in outer)
{
    yield return resultSelector(current, lookup[outerKeySelector(current)].DefaultIfEmpty());
}
Run Code Online (Sandbox Code Playgroud)

c# linq

4
推荐指数
1
解决办法
1527
查看次数

VS2010不符合C#4.0规范中的"用户定义的转换评估"吗?

如果使用Visual Studio 2010编译以下代码:

    public struct A
    {
        public static implicit operator B(A a)
        {
            Console.WriteLine("11111111111");
            return new B();
        }
    }
    public struct B
    { }
    public static B F(A? a)
    {
        return (B)a;
    }
Run Code Online (Sandbox Code Playgroud)

使用ILSpy,return (B)a;实际编译为return A.op_Implicit(a.value).

根据我对C#4.0第6.4.5节"用户定义的显式转换"的理解,它应该产生编译器错误.

但是,阅读ECMA 334第13.4.4节"用户定义的显式转换",它有一个不同的规则,上面的代码似乎符合这一规则.

C#4.0:

查找适用的用户定义和提升转换运算符集合U.此集合包含由 D中的类或结构声明的用户定义和提升的隐式或显式转换运算符,这些运算符从包含或包含在S中的类型转换为T包含或包含T.如果U为空,则转换未定义,并发生编译时错误.

ECMA 334:

找到适用的转换运算符集合U.这个集合包含用户定义的,如果S和T都可以为,则提升隐式或显式转换运算符(第13.7.3节),由转换为D的类或结构声明从包含或包含在S中的类型到包含或包含在T中的类型.如果U为空,则不存在转换,并且发生编译时错误.

我是否认为VS2010不符合C#4.0规范中的"用户定义的转换评估"部分,但是是否符合ECMA规范?

c# syntax

4
推荐指数
1
解决办法
246
查看次数

为什么MemoryBarrier可以通过调用xchg来实现?

在msdn http://msdn.microsoft.com/en-us/library/windows/desktop/ms684208(v=vs.85).aspx上,MemoryBarrier是作为对xchg的调用来实现的。

// x86

FORCEINLINE
VOID
MemoryBarrier (
    VOID
    )
{
    LONG Barrier;
    __asm {
        xchg Barrier, eax
    }
}
Run Code Online (Sandbox Code Playgroud)

我在“软件开发人员手册”中找不到一些材料。请告诉我原因。

windows x86 msdn memory-barriers

3
推荐指数
1
解决办法
878
查看次数

为什么在将int转换为char时没有溢出警告

int i=9999;  

char c=i;  
Run Code Online (Sandbox Code Playgroud)

没有溢出警告,而

char c=9999;  
Run Code Online (Sandbox Code Playgroud)

给,

警告C4305初始化从int到char的截断

为什么没有溢出转换时警告intchar

c visual-c++

0
推荐指数
1
解决办法
408
查看次数