我正在玩,delegates并注意到当我创建一个Func<int,int,int>类似下面的例子时:
Func<int, int, int> func1 = (x, y) => x * y;
Run Code Online (Sandbox Code Playgroud)
编译器生成的方法的签名不是我所期望的:

正如您所看到的,它需要一个对象作为它的第一个参数.但是当有一个关闭时:
int z = 10;
Func<int, int, int> func1 = (x, y) => x * y * z;
Run Code Online (Sandbox Code Playgroud)
一切都按预期工作:

这是带有额外参数的方法的IL代码:
.method private hidebysig static int32 '<Main>b__0'(object A_0,
int32 x,
int32 y) cil managed
{
.custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor() = ( 01 00 00 00 )
// Code size 8 (0x8)
.maxstack 2
.locals init ([0] int32 V_0)
IL_0000: ldarg.1
IL_0001: ldarg.2
IL_0002: mul …Run Code Online (Sandbox Code Playgroud) 我想要一个可选参数并将其设置为我确定的默认值,当我这样做时:
private void Process(Foo f = new Foo())
{
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误(Foo是一个类):
'f'是Foo的类型,除string之外的引用类型的默认参数只能用null初始化.
如果我Foo改为struct那么它可以工作,但只有默认的无参数构造函数.
我阅读了文档,它清楚地表明我不能这样做,但它没有提到为什么?,为什么这个限制存在,为什么string被排除在外呢?为什么可选参数的值必须是编译时常量?如果那不是一个常数那么副作用会是什么?
我知道在.NET中,所有数组都派生自System.Array并且System.Array类实现IList,ICollection和IEnumerable.实际的数组类型也实现IList<T>,ICollection<T>和IEnumerable<T>.
这意味着如果你有一个String[],那么那个String[]对象也是a System.Collections.IList和a System.Collections.Generic.IList<String>;.
不难看出为什么那些IList会被认为是"ReadOnly",但令人惊讶的是......
String[] array = new String[0];
Console.WriteLine(((IList<String>)array).IsReadOnly); // True
Console.WriteLine(((IList)array).IsReadOnly); // False!
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,尝试通过Remove()和RemoveAt()方法删除项会导致NotSupportedException.这表明两个表达式都对应于ReadOnly列表,但IList的ReadOnly属性不返回预期值.
怎么会?
我刚刚发布了这个问题的答案,但我并不完全相信我的答案.我想知道有两件事,请考虑以下代码:
class Foo<T>
{
void SomeMethod()
{
string str = "foo";
Foo<T> f = str as Foo<T>;
}
}
Run Code Online (Sandbox Code Playgroud)
据说C# Specification 5.0,有两种不同的转换方式as operator.
如果编译时类型
E不是dynamic,则操作E as T产生与之相同的结果Run Code Online (Sandbox Code Playgroud)E is T ? (T)(E) : (T)null如果编译时类型
E是dynamic,则与as operator强制转换运算符不同,它不是动态绑定的(第7.2.2节).因此,在这种情况下的扩展是:Run Code Online (Sandbox Code Playgroud)E is T ? (T)(object)(E) : (T)null
因为,这是无效的 (Foo<T>)str
str is Foo<T> ? (Foo<T>)str : (Foo<T>)null;
Run Code Online (Sandbox Code Playgroud)
我认为它应该被翻译为:
str is Foo<T> ? (Foo<T>)(object)str : …Run Code Online (Sandbox Code Playgroud) 有没有办法bootstrap通过调用函数来获取版本?我做了一些研究,但找不到任何方法,版本信息包含在开头的评论中,如下所示:
/*!
* Bootstrap v3.3.7 (http://getbootstrap.com)
* Copyright 2011-2016 Twitter, Inc.
* Licensed under the MIT license
*/
但是如果删除了注释,我该如何获得引导版本?Bootstrap插件有一个版本定义,但我正在寻找一般的bootstrap版本,而不是特定插件的版本.
我有这种代码
static void Main(string[] args)
{
byte[] array = new byte[2] { 0x00, 0x1f };
Console.WriteLine(BitConverter.ToInt32(array, 0));
}
Run Code Online (Sandbox Code Playgroud)
但它不起作用.它引发了一个异常:
目标数组不够长,无法复制集合中的所有项目.检查数组索引和长度.
怎么了?
我想知道如何is operator实现C#.我已经编写了一个简单的测试程序(没有什么特别的,仅用于演示目的):
class Base
{
public void Display() { Console.WriteLine("Base"); }
}
class Derived : Base { }
class Program
{
static void Main(string[] args)
{
var d = new Derived();
if (d is Base)
{
var b = (Base) d;
d.Display();
}
}
}
Run Code Online (Sandbox Code Playgroud)
并查看生成的IL代码:
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 27 (0x1b)
.maxstack 2
.locals init ([0] class ConsoleApplication1.Derived d,
[1] bool V_1,
[2] …Run Code Online (Sandbox Code Playgroud) 我正在使用Entity Framework 6.1,我有一个这样的代码:
Brand b;
using(var ctx = new KokosEntities())
{
try
{
b = ctx.Brands.Find(_brands[brandName].Id);
return b;
}
catch (Exception ex)
{
_logger.Log(LogLevel.Error, ex);
}
}
Run Code Online (Sandbox Code Playgroud)
这会产生:
N'SELECT TOP (2)
[Extent1].[Id] AS [Id],
[Extent1].[Name] AS [Name],
[Extent1].[OpenCartId] AS [OpenCartId]
FROM [dbo].[Brands] AS [Extent1]
WHERE [Extent1].[Id] = @p0',N'@p0 int'
Run Code Online (Sandbox Code Playgroud)
Find方法返回单个结果,但它生成一个TOP(2)查询而不是1.为什么?
注意:我确定我正确Id地传递给方法,是的,Id是主键.
我有一个像这样的空体的方法:
public void Foo()
{
}
Run Code Online (Sandbox Code Playgroud)
正如ReSharper我所建议的那样,我希望将其转换为表达式主体以节省一些空间,它变为:
public void Foo() => ;
Run Code Online (Sandbox Code Playgroud)
哪个不编译.是否有特定原因导致不支持此操作?
而且我认为我应该打开一个错误票,ReSharper因为它将代码重构为不可编译的版本.
我有这样的代码,发出一些IL调用指令string.IndexOf一对null对象:
MethodBuilder methodBuilder = typeBuilder.DefineMethod(
"Foo",
MethodAttributes.Public,
typeof(void), Array.Empty<Type>());
var methodInfo = typeof(string).GetMethod("IndexOf", new[] {typeof(char)});
ILGenerator ilGenerator = methodBuilder.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldnull);
ilGenerator.Emit(OpCodes.Ldc_I4_S, 120);
ilGenerator.Emit(OpCodes.Call, methodInfo);
ilGenerator.Emit(OpCodes.Ret);
Run Code Online (Sandbox Code Playgroud)
这是生成的IL代码:
.method public instance int32 Foo() cil managed
{
// Code size 12 (0xc)
.maxstack 2
IL_0000: ldnull
IL_0001: ldc.i4.s 120
IL_0003: nop
IL_0004: nop
IL_0005: nop
IL_0006: call instance int32 [mscorlib]System.String::IndexOf(char)
IL_000b: ret
} // end of method MyDynamicType::Foo
Run Code Online (Sandbox Code Playgroud)
如您所见,nop指令前有三条call指令.
首先我考虑了Debug/Release构建,但这不是编译器生成的代码,我发出了原始的IL代码,并希望看到它原样.
所以我的问题是为什么 …
c# ×9
.net ×2
arrays ×2
cil ×2
as-operator ×1
c#-7.0 ×1
casting ×1
delegates ×1
dynamic ×1
generics ×1
il ×1
ilgenerator ×1
javascript ×1
resharper ×1
sql ×1