C#中的#include指令

时间:2010-01-25 17:05:10

标签: c#

有更换吗?如果有,指令将如何查找名为“class.cs”的文件? 我只想将代码拆分为每个类的文件。

10 个答案:

答案 0 :(得分:11)

不,#include语句没有替代品。 C#是一种面向对象的语言,其中代码被组织成类。您可以根据其可见性使用另一个类中的一个类的代码,并且可以使用分部类将代码从单个类拆分为多个源文件。这些基本上就是你在另一个“文件”中使用代码的方式。但这根本不是一回事。

答案 1 :(得分:9)

在C#(超越泛型)中实现元编程的惯用方法是使用T4模板 - Visual Studio和MSBuild支持T4内置,但是VS没有T4语法着色 - 你需要第三方添加 - 为了那个。

为了演示T4的include功能,我将使用想要在不使用继承的情况下同时向多个类添加==运算符重载的场景。

为了比较,在C ++中它将是这样的:

OperatorEquals.inc

bool operator==(const TYPE* lhs, const TYPE* rhs) { if( lhs == nullptr && rhs != nullptr ) return false; return lhs.Equals(rhs); }

Code.h

class Foo {
public:
#define TYPE Foo
#include "OperatorEquals.inc"
}

class Bar {
public:
#define TYPE Bar
#include "OperatorEquals.inc"
}

在C#中,你会这样做:

  1. 使用partial类,以便所有非元编程逻辑(即普通C#代码)都在文件中,例如: Foo.csBar.cs
  2. 在项目中创建新的T4模板,将输出文件扩展名更改为.cs
  3. 在该T4(partial class)文件中创建相同类型的第二个*.tt定义,但您不会突出显示C#语法。
  4. 定义包含的文件:
  5. Operators.inc.cs.t4

    public static operator==(<#= typeName #> x, <#= typeName #> y) {
        if( x == null && y != null ) return false;
        return x.Equals( y );
    }
    
    1. 将其添加到您的T4模板:
    2. Metaprogramming.tt

      <#@ template debug="false" hostspecific="false" language="C#" #>
      <#@ import namespace="System" #>
      <#@ output extension=".cs" #>
      <# String typeName = null; #>
      
      public partial class Foo {
      
          <# typeName = "Foo"; #>
          <#@ include file="Operators.inc.cs.t4" #>
      }
      
      public partial class Bar {
      
          <# typeName = "Bar"; #>      
          <#@ include file="Operators.inc.cs.t4" #>
      }
      

      每当您“保存”.tt文件时(即使您不做任何更改),VS也会重新生成输出.cs文件,如下所示:

      public partial class Foo {
      
          public static operator==(Foo x, Foo y) {
             if( x == null && y != null ) return false;
             return x.Equals( y );
         }
      }
      
      public partial class Bar {
      
         public static operator==(Bar x, Bar y) {
             if( x == null && y != null ) return false;
             return x.Equals( y );
         }
      }
      

      请注意,此方案是设计的 - 如果您确实要添加operator==(以及所有其他人:IEquatable<T>operator!=IComparable<T>等,那么你可能会使用T4渲染函数而不是include,因为这样可以使参数化变得更加简单,并将所有内容保存在一个文件中:

      T4RenderFunction.tt

      <#@ template debug="false" hostspecific="false" language="C#" #>
      <#@ import namespace="System" #>
      <#@ output extension=".cs" #>
      <# String typeName = null; #>
      
      public partial class Foo {
      
          <# RenderBoilerplateOperators("Foo"); #>
      }
      
      public partial class Bar {
      
          <# RenderBoilerplateOperators("Bar"); #>
      }
      
      <#+
      // Functions are declared at the bottom
      void RenderBoilerplateOperators(String typeName) {
      #>
          public static operator==(<#= typeName #> lhs, <#= typeName #> rhs) {
              return <#= typeName #>.Equals( lhs, rhs );
          }
      
          public override Boolean Equals(<#= typeName #> other) {
              return <#= typeName #>.Equals( this, other );
          }
      
          public static Boolean Equals(<#= typeName #> lhs, <#= typeName #> rhs) {
              // T4 can use VS DTE to enumerate members of `typeName`, but you're probably better-off implementing this method manually
          }
      
          public static operator!=(<#= typeName #> lhs, <#= typeName #> rhs) {
              return !<#= typeName #>.Equals( lhs, rhs );
          }
      
          // and so on...
      <#
      } // void RenderBoilerplateOperators
      #>
      

答案 2 :(得分:5)

与C#中的C或C ++不同,不需要使用#include来使用其他文件中定义的类型。而C#则基于容器(如类或命名空间)进行类型解析。只要两个文件都包含在编译中并且第二种类型的命名空间可用,那么您的类就可以访问。

示例:

的Class1.cs

namespace Project1 { 
 class Class1 { ... }
}

Class2.cs

namespace Project1 {
  class Class2 {
    private Class1 m_field1;
    ..
  }
}

答案 3 :(得分:4)

另外,不要忘记C#部分类具有一些您可能通过#include语句获得的功能。

部分类允许您将类定义拆分为多个文件。

答案 4 :(得分:3)

有点不清楚你的意思。但是你在考虑:

using MyNamespace;

答案 5 :(得分:2)

答案 6 :(得分:2)

如果您使用msbuild或在csc(C#编译器)命令行中,则将每个文件包含在* .csproj中:

csc File1.cs File2.cs

http://msdn.microsoft.com/en-us/library/78f4aasd%28VS.80%29.aspx

答案 7 :(得分:1)

这与C的#include指令不完全相同,但是C#的using statement就是你所追求的:

using Assembly.Name;

它在命名空间级别而不是文件级别工作。因此,如果class.csSomeClass命名空间中包含名为Application.Core的公共类,则可能如下所示:

using Application.Core;

这通常位于您正在使用的文件的顶部,并允许该类使用SomeClass作为对象(以及Application.Core命名空间中的所有其他公共类)。 / p>

当然,如果这些类都在同一名称空间中(例如Application.Core),则根本没有理由使用using语句。相同名称空间中的类可以在没有任何声明的情况下相互解析。

答案 8 :(得分:0)

您需要将class.cs的内容放入命名空间。然后在需要查看class.cs的文件顶部放置一个using语句。

class.cs
namespace Class {
//class.cs stuff
}

然后在需要类的文件中执行以下操作。

  using Class;

答案 9 :(得分:0)

使用Partial Class的示例。

Main.cs

partial class Program
{
    private static void Main()
    {
        A();
        B();
    }
}

fileA.cs

partial class Program
{
    private static void A() => Console.WriteLine("A");
}

fileB.cs

partial class Program
{
    private static void B() => Console.WriteLine("B");
}