有更换吗?如果有,指令将如何查找名为“class.cs”的文件? 我只想将代码拆分为每个类的文件。
答案 0 :(得分:11)
不,#include语句没有替代品。 C#是一种面向对象的语言,其中代码被组织成类。您可以根据其可见性使用另一个类中的一个类的代码,并且可以使用分部类将代码从单个类拆分为多个源文件。这些基本上就是你在另一个“文件”中使用代码的方式。但这根本不是一回事。
答案 1 :(得分:9)
在C#(超越泛型)中实现元编程的惯用方法是使用T4模板 - Visual Studio和MSBuild支持T4内置,但是VS没有T4语法着色 - 你需要第三方添加 - 为了那个。
为了演示T4的include
功能,我将使用想要在不使用继承的情况下同时向多个类添加==
运算符重载的场景。
为了比较,在C ++中它将是这样的:
bool operator==(const TYPE* lhs, const TYPE* rhs) { if( lhs == nullptr && rhs != nullptr ) return false; return lhs.Equals(rhs); }
class Foo {
public:
#define TYPE Foo
#include "OperatorEquals.inc"
}
class Bar {
public:
#define TYPE Bar
#include "OperatorEquals.inc"
}
在C#中,你会这样做:
partial
类,以便所有非元编程逻辑(即普通C#代码)都在文件中,例如: Foo.cs
和Bar.cs
.cs
partial class
)文件中创建相同类型的第二个*.tt
定义,但您不会突出显示C#语法。public static operator==(<#= typeName #> x, <#= typeName #> y) {
if( x == null && y != null ) return false;
return x.Equals( y );
}
<#@ 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,因为这样可以使参数化变得更加简单,并将所有内容保存在一个文件中:
<#@ 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.cs
在SomeClass
命名空间中包含名为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");
}