C#中的#include指令

Rom*_* C. 12 c#

有替代品吗?如果有,指令将如何查找名为"class.cs"的文件?我只想将代码拆分为每个类的文件.

Dai*_*Dai 11

在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); }
Run Code Online (Sandbox Code Playgroud)

Code.h

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

class Bar {
public:
#define TYPE Bar
#include "OperatorEquals.inc"
}
Run Code Online (Sandbox Code Playgroud)

在C#中,你会这样做:

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

Operators.inc.cs.t4

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

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" #>
}
Run Code Online (Sandbox Code Playgroud)

每当您"保存" .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 );
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意,这种情况下是做作-如果你真的想要添加的operator==(和所有其他人:IEquatable<T>,operator!=,IComparable<T>,等),那么你可能会使用一个T4渲染,而不是包括功能,因为这使得参数更简单,使一切自我 - 包含在一个文件中:

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
#>
Run Code Online (Sandbox Code Playgroud)


Dav*_*d M 10

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

  • -1表示完全没有抓住要点。问题是要求一个指令,相当于 C++ 中的“#include”,该指令就是“using”语句。此外,C# 与 C++ 一样都是面向对象的(解读:完全不是)。这两种语言都允许开发人员编写面向对象的代码。但这与问题完全无关。 (4认同)

Jar*_*Par 5

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

例:

将Class1.cs

namespace Project1 { 
 class Class1 { ... }
}
Run Code Online (Sandbox Code Playgroud)

Class2.cs

namespace Project1 {
  class Class2 {
    private Class1 m_field1;
    ..
  }
}
Run Code Online (Sandbox Code Playgroud)


Gab*_*ana 5

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

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