C# - 类,构造函数和Resharper - 澄清

时间:2012-09-17 06:02:26

标签: c# .net visual-studio-2010 resharper

我在visual studio中使用Resharper工具

考虑下面写的一个非常简单的类。

class Test()
{

   //constructors do not have any return type.   
   Test()
   {
      System.Console.WriteLine("Hello World!");
   } 

   static Test()
   {
        System.Console.WriteLine("Hello World in Static constructors");
   }

   public void A()
   {
      System.Console.WriteLine("A simple function in a class");
   }

}


class Program
  {
    static void Main(string[] args)
    {
        var asa = new Test(); //Implicitly Typed local variables.
        asa.A();

    }
}

使用var(编译器必须从表达式中推断出变量的类型 初始化语句的右侧)。

我有一些澄清问题,它们在下面。

  1. 编译器的额外负担?
  2. 一个班级可以拥有多少个构造函数?
  3. 为什么静态构造函数首先被调用? (我通过断点检查了一下?)
  4. 为什么不测试asa = new Test(); Resharper不首选?
  5. 首先使用Resharper作为初学者真的是个好主意吗? (我自己是C和.net编程的新手!)
  6. 先谢谢。

4 个答案:

答案 0 :(得分:7)

  1. 编译器的任何额外负担基本上无关紧要 - 它不应成为您决定是否使用var的一部分。正如评论中所指出的,当您使用显式声明的变量时,编译器可能需要稍微更多的工作......但同样,它并不重要。

  2. 一个类可以有任意数量的构造函数......虽然很快就会变得难以处理。

  3. 在第一次使用类之前,静态构造函数将被称为一次(无论是通过静态方法还是构造函数调用)。阅读C#规范了解更多详情 - C#5规范的第10.12节包括:

      

    封闭类类型的静态构造函数在给定的应用程序域中最多执行一次。静态构造函数的执行由应用程序域中发生的以下第一个事件触发:

         
        
    • 创建了类类型的实例。
    •   
    • 引用类类型的任何静态成员。
    •   
  4. 您可以将ReSharper配置为建议替代方案,或将其视为警告等。在此方面让您认为应该可行。

答案 1 :(得分:2)

  1. 如果有的话可以忽略不计。否则将返回编译检查返回类型。无论如何,你不应该根据它作出决定。
  2. 只要能够区分,就可以随心所欲。
  3. 静态构造函数是类型定义的一部分。首次引用类型时会调用它们。
  4. 您收到了什么消息? R#是可配置的。
  5. 编辑: (你无法击败Skeet。)

答案 2 :(得分:2)

  1. 是的,还需要一些额外的工作,但只有在编译器很容易推断出类型的情况下才可以使用var关键字。

    < / LI>
  2. 构造函数的 number 没有约束,但是构造函数必须遵循一些规则(即:编译器需要清楚哪个构造函数要调用)

  3. 我无法告诉你为什么 - 让我们说这只是其中一条规则。有趣的是beforefieldinit(http://stackoverflow.com/questions/610818/what-does-beforefieldinit-flag-do, http://csharpindepth.com/Articles/General/Beforefieldinit.aspx

  4. 我个人认为在这种情况下,这只是一个品味问题。有些人倾向于尽可能多地使用var,而其他人则相反。我试着在以下时间使用:

    • 我正在使用集合(或者需要大量文本来告诉编译器类型:而不是:
  5. Dictionary<<OneOfMyClasses, OtherClasss> dictionary = new Dictionary<OneOfMyClasses, OtherClass>();
    

    我倾向于使用var

    var dictionary = new Dictionary<OneOfMyClasses, OtherClass>();
    

    请注意,它不会影响代码的可读性(即,仍然很容易理解实际发生的情况)。

答案 3 :(得分:0)

谢谢大家。花了一些时间研究,我想补充一些可能对某人有帮助的观点。

免责声明:(以下几点是从codeproject和其他此类网站派生(甚至粘贴)的。

1)每个类只能有一个静态构造函数。

原因:静态构造函数必须是无参数或简单,不允许构造函数重载。由于CLR将调用此构造函数,因此我们无法控制将值传递给此函数。由于我们无法直接调用静态构造函数,因此没有必要使用多个静态构造函数。

class Test
{
   static Test() {...}
   static Test(int a) {...} //would throw error as "Static constructor must be parameter less"
}

2)应声明静态构造函数,不带任何访问说明符。

原因:CLR再次调用静态构造函数而不是类的任何对象。因此,我们不需要任何访问说明符。

3)静态构造函数必须只对该类的静态变量

起作用

原因:非静态成员特定于对象实例。修改其值取决于/绑定到其特定对象实例的变量没有意义。

4)为什么要使用静态构造函数?给我一个很好的例子

原因:您可以使用静态构造函数,例如,当您要记录要使用该类执行的操作时。 MSDN说“静态构造函数的典型用法是当类使用日志文件并且构造函数用于将条目写入此文件时”。

5)何时调用一个静态构造函数?

答案:用户无法控制程序中何时执行静态构造函数。 。正如其他人和MSDN所指出的那样“在创建第一个实例或引用任何静态成员之前,会自动调用静态构造函数来初始化类。”

6)在C#中使用基类和派生类时,在创建派生类的新实例时,是先调用基类构造函数还是首先调用派生类构造函数?

答案:首先调用基类构造函数,然后调用派生类构造函数。

代码示例

class DerivedClass : ParentClass
{
     public DerivedClass()
     {
         Console.WriteLine("Derived class constructor!");
     }

}

 class ParentClass
{
     public ParentClass()
     {
         System.Console.WriteLine("Parent class constructor!");
     }
}

class Program
{
    static void Main(string[] args)
    {

        var a = new DerivedClass(); //Implicitly Typed local variables.

    }
}

7)为什么在上面的例子中,两个构造函数都有公共访问说明符?如果我指定私有或不指定访问说明符,该怎么办?

答案:当您未指定访问说明符(此情况下,构造函数自动变为私有)或每当您使用私有访问说明符时,无法实例化该类。每当一个类包含一个或多个私有构造函数时,它就严格(!)无法实例化。这种类型的构造函数称为特殊实例构造函数,通常在类的所有成员都是静态方法时使用。 (可能数学课应该是一个很好的例子。)

** 8)关于继承的奖金问题。一个类是从两个不同的类继承吗?

严格来说,C#只支持直接继承,当然你可以使用接口。例如,

    interface Test
   {
         void abc();
   }  
   class DerivedClass : ParentClass, Test //Test should not be a class. It can be  a interface.
{
     public DerivedClass()
     {
         Console.WriteLine("Derived class constructor!");
     }

     public void abc()
     {
          //should be publicly defined!
          //non public method could not implement from interface Test
     }

}

 class ParentClass
{
     public ParentClass()
     {
         System.Console.WriteLine("Parent class constructor!");
     }
}