小编Ily*_*nov的帖子

为什么递归构造函数调用会使无效的C#代码编译?

在观看网络研讨会Jon Skeet Inspects ReSharper之后,我开始尝试使用递归构造函数调用,并发现以下代码是有效的C#代码(有效我的意思是它编译).

class Foo
{
    int a = null;
    int b = AppDomain.CurrentDomain;
    int c = "string to int";
    int d = NonExistingMethod();
    int e = Invalid<Method>Name<<Indeeed();

    Foo()       :this(0)  { }
    Foo(int v)  :this()   { }
}
Run Code Online (Sandbox Code Playgroud)

我们都知道,字段初始化由编译器移动到构造函数中.所以,如果你有一个字段一样int a = 42;,你将不得不a = 42所有构造函数.但是如果你有构造函数调用另一个构造函数,那么只有被调用的构造函数才会有初始化代码.

例如,如果您使用带有参数调用默认构造函数的构造函数,则a = 42只能在默认构造函数中进行赋值.

为了说明第二种情况,下一个代码:

class Foo
{
    int a = 42;

    Foo() :this(60)  { }
    Foo(int v)       { }
}
Run Code Online (Sandbox Code Playgroud)

编译成:

internal class Foo
{ …
Run Code Online (Sandbox Code Playgroud)

c#

81
推荐指数
2
解决办法
4229
查看次数

为什么在泛型类中使用重复嵌套类型的字段声明会导致巨大的源代码增加?

场景非常罕见,但非常简单:定义一个泛型类,然后创建一个嵌套类,它继承自外部类并在嵌套中定义一个关联字段(self类型).代码片段比描述更简单:

class Outer<T>
{
    class Inner : Outer<Inner>
    {
        Inner field;
    }
}
Run Code Online (Sandbox Code Playgroud)

在反编译IL之后,C#代码如下所示:

internal class Outer<T>
{
    private class Inner : Outer<Outer<T>.Inner>
    {
        private Outer<Outer<T>.Inner>.Inner field;
    }
}
Run Code Online (Sandbox Code Playgroud)

这看起来很公平,但是当你改变字段的类型声明时,事情变得更加棘手.所以当我将字段声明更改为

Inner.Inner field;
Run Code Online (Sandbox Code Playgroud)

反编译后,此字段将如下所示:

private Outer<Outer<Outer<T>.Inner>.Inner>.Inner field;
Run Code Online (Sandbox Code Playgroud)

我明白,这个类'嵌套'和继承彼此并不相处,但为什么我们会观察到这种行为呢?在 Inner.Inner 类型声明已经发生任何变化的类型?是 Inner.Inner Inner 类型,在此情况下某种方式有什么不同?

当事情变得非常棘手

您可以在下面看到该类的反编译源代码.它非常庞大,总长度为12159个符号.

class X<A, B, C>
{
    class Y : X<Y, Y, Y>
    {
        Y.Y.Y.Y.Y.Y y;
    }
} 
Run Code Online (Sandbox Code Playgroud)

最后,这堂课:

class X<A, B, C, D, E>
{
    class Y : X<Y, Y, Y, Y, Y> …
Run Code Online (Sandbox Code Playgroud)

.net c# generics nested c#-4.0

39
推荐指数
3
解决办法
1435
查看次数

如何使乘法运算符(*)表现为短路?

我有很多计算,特别是乘法,其中第一部分有时为零,在这种情况下我不想评估第二个操作数.C#中至少有两个短路运算符:&&并且||仅在必要时才评估第二个操作数.我想用乘法运算符实现类似的行为.

.net中,您不能&&直接重载操作符,但您可以重载&false操作符,这样您就可以使用扩展点来改变短路操作符的行为.您可以在本文中找到更多详细信息C#运算符重载:'&&'运算符

是否有任何方法可以实现乘法运算符的这种或类似的行为?

这是一个纯语法问题,因为实现非常简单.下一个方法在功能方面完全符合我的要求:

public static double ShortCircuitMultiply(double val, Func<double> anotherValue)
{
    var epsilon = 0.00000001;
    return Math.Abs(val) < epsilon ? 0 : val * anotherValue();
}
Run Code Online (Sandbox Code Playgroud)

注:此实现不充分:在C#中,如果你乘0.0Double.NaN 或者Double.NegativeInfinity或者Double.PositiveInfinity,你会得到NaN,但在以下方面ShortCircuitMultiply-只有零.让我们忽略这个细节,它在我的领域真的无关紧要.

所以,现在如果我把它作为ShortCircuitMultiply(0.0, longOperation)地方longOperationFunc<double>,上学期将不进行评估和操作的结果将是有效为零.

问题是,正如我已经说过的,我会有很多ShortCircuitMultiply调用,我想让代码更具可读性.我希望代码与可能的代码类似0.0 * longOperation().


另一个注意事项:我已经尝试构建包装器double并创建隐式转换以加倍并且还重载*运算符.我明白,这可能是多余的:我想要实现可读性,但试图建立另一个包装器.无论如何,下一个代码演示了我的意图:

class …
Run Code Online (Sandbox Code Playgroud)

c# operator-overloading short-circuiting

16
推荐指数
2
解决办法
1910
查看次数

如何基于封闭泛型类型调用方法重载?

假设我有三种方法:

void Foo(MemoryStream v) {Console.WriteLine ("MemoryStream");}
void Foo(Stream v)       {Console.WriteLine ("Stream");}
void Foo(object v)       {Console.WriteLine ("object");}
Run Code Online (Sandbox Code Playgroud)

我调用方法Foo传递开放泛型类型的第一个参数:

void Bar<T>()
{
    Foo(default(T)); //just to show the scenario
    //default(T) or new T() doesn't make a difference, null is irrelevant here
}
Run Code Online (Sandbox Code Playgroud)

我想打电话给MemoryStream超载,所以我关闭泛型类型的方法BarMemoryStream:

Bar<MemoryStream>();
Run Code Online (Sandbox Code Playgroud)

object过度被称为.如果我将通用约束添加到Foo签名where T : Stream,则Stream调用该版本.

有没有办法MemoryStream根据开放泛型类型调度方法调用重载T

我不想使用Delegate.CreateDelegate或其他Reflection API.只是在C#语言的手段.我可能在语言本身内遗漏了一些东西.

尝试使用值类型作为封闭泛型类型并使用静态方法来实现此方案.

c# generics

12
推荐指数
3
解决办法
2799
查看次数

如何解决Enumerable和MoreLINQ之间的模糊ZIP调用?

我遇到了扩展方法解决方案的问题.LINQ和MoreLINQ包含zip方法,它从4.0版本开始在.NET中出现,并且始终在MoreLINQ库中.但是您不能使用具有良好旧扩展方法语法的实现之一.所以这段代码不会编译

using MoreLinq;
using System.Linq;


var students = new [] { "Mark", "Bob", "David" };
var colors = new [] { "Pink", "Red", "Blue" };

students.Zip(colors, (s, c) => s + c );
Run Code Online (Sandbox Code Playgroud)

错误:

The call is ambiguous between the following methods or properties: 
'MoreLinq.MoreEnumerable.Zip<string,string,string>
(System.Collections.Generic.IEnumerable<string>, 
System.Collections.Generic.IEnumerable<string>, System.Func<string,string,string>)' and 
'System.Linq.Enumerable.Zip<string,string,string>
(System.Collections.Generic.IEnumerable<string>, 
System.Collections.Generic.IEnumerable<string>, System.Func<string,string,string>)'
Run Code Online (Sandbox Code Playgroud)

我已经找到了Jon Skeet在这篇文章中为MoreLINQ制作Concat方法的好分辨率,但是我不知道方法的好分辨率.stringzip

注意:您始终可以使用静态方法调用语法,并且一切正常

MoreEnumerable.Zip(students, colors, (s, c) => s + c )
Run Code Online (Sandbox Code Playgroud)

但是错过了扩展语法糖点的一点点.如果您使用LINQ和MoreLINQ调用进行大量数据转换 - …

.net c# linq ambiguous-call morelinq

11
推荐指数
2
解决办法
1746
查看次数

如何断言所有选定的属性都已设置(非空或空)

我想验证(断言)我的DTO对象上的某些属性是否已设置.我试图用Fluent Assertions来做,但以下代码似乎不起作用:

mapped.ShouldHave().Properties(
    x => x.Description,
    ...more
    x => x.Id)
    .Should().NotBeNull(); 
Run Code Online (Sandbox Code Playgroud)

是否可以通过Fluent Assertions或其他工具实现这一目标?Fluent断言具有ShouldBeEquivalentTo,但实际上我只关心那些是不是空/空,所以我无法使用.

当然我可以在每个属性级别上做一个Assert,但是对一些更优雅的方式感兴趣.

.net c# fluent-assertions

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

为什么编译器不会将"this"链接转换为上下文无关变量?

假设我有一个班级(非常简单的场景)

class Student
{
    name = "John";

    sayHello()
    {
        console.log("Hi, I'm " + this.name);
    }
}
Run Code Online (Sandbox Code Playgroud)

它由TypeScript编译器编译为:

var Student = (function () {
    function Student() {
        this.name = "John";
    }
    Student.prototype.sayHello = function () {
        console.log("Hi, I'm " + this.name); //here is the problem. Accessing name via this
    };
    return Student;
})();
Run Code Online (Sandbox Code Playgroud)

现在,如果我创建一个对象并调用一个方法,一切正常.

var student = new Student();

student.sayHello(); //prints Hi, I'm John
Run Code Online (Sandbox Code Playgroud)

但是如果我从回调中调用该方法,它就会中断(this正如预期的那样引用一个Window)

setTimeout(student.sayHello); //prints Hi, I'm 
Run Code Online (Sandbox Code Playgroud)

我知道thisJavaScript和C#或Java 之间的区别.我也知道,TypeScript试图解决这个差异.例如这段代码:

class Student
{
    name = "John"; …
Run Code Online (Sandbox Code Playgroud)

javascript typescript

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

如何将选定的项目ID从下拉列表传递给控制器​​的操作?

一般问题概述:我有一个复合项的create\edit视图,我从下拉列表中为组件选择了很多选项.我希望能够添加或编辑在下拉列表中选择的特定组件.

这是一个简短但完整的例子:

假设我有一个Car模型

public class Car
{
    public int Id { get; set; }
    public string Name { get; set; }

    public BodyStyle BodyStyle { get; set; }
    public int BodyStyleId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

BodyStyleCar聚合的一个组成部分,定义如下:

public class BodyStyle
{
    public int Id { get; set; }
    public string Name { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

现在我有一个控制器动作来创建一辆汽车,

public ActionResult CreateCar()
{
    //BodyStyles is a mock property with all hardcoded BodyStyles, just for demo …
Run Code Online (Sandbox Code Playgroud)

c# asp.net asp.net-mvc razor asp.net-mvc-4

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

如何在c#中对这个方法进行单元测试?

我正在学习单元测试.如何使用nunit和rhino mock对这个方法进行单元测试?

public ActionResult PrintCSV(Byte[] bytes, string fileName)
{
    var file = File(bytes, "application/vnd.ms-excel");
    var cd = new System.Net.Mime.ContentDisposition()
    {
        CreationDate = DateTime.Now,
        FileName = fileName,
        Inline = false
    };
    Response.AppendHeader("Content-Disposition", cd.ToString());
    return file;
}
Run Code Online (Sandbox Code Playgroud)

c# nunit asp.net-mvc-3

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

在c#中找到一个形状的外接圆和内圆

我需要找到这种形状的外接圆和内圆

在此输入图像描述

我的代码找到了外接圆,但是外圆是错的

for (int r = 1; ; r++) //r is radius
{
    int found = 0; //counts found pixels
    int wrong = 0; //counts pixels that are on the circle but have different color that desirable
    int good = 0; //counts pixels that are on the circle with desirable color
    for (int y = point.Y - r ; y <= point.Y + r ; y++) //point is the center of the figure (110,110)
    {
        for (int x = point.X …
Run Code Online (Sandbox Code Playgroud)

c# math

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