繁体   English   中英

C#中的#include指令

[英]#include directive in C#

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

在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( *.tt )文件中创建相同类型的第二个partial class定义,但您不会使用C#语法突出显示。
  4. 定义包含的文件:

Operators.inc.cs.t4

public static operator==(<#= typeName #> x, <#= typeName #> y) {
    if( x == null && y != null ) return false;
    return x.Equals( y );
}
  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" #>
}

每当你“保存” .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== (以及所有其他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
#>

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

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

例:

将Class1.cs

namespace Project1 { 
 class Class1 { ... }
}

Class2.cs

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

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

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

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

using MyNamespace;

看看使用声明

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

csc File1.cs File2.cs

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

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

using Assembly.Name;

它在命名空间级别而不是文件级别工作。 因此,如果class.csApplication.Core命名空间中包含名为SomeClass的公共类,则它看起来像:

using Application.Core;

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

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

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

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

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

  using Class;

使用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");
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM