Есть ли замена? Если есть, как бы директива искала файл с именем "class.cs"? Я просто хочу разбить код на файл для каждого класса.
Директива #include в С#
Ответ 1
Нет, нет замены для оператора #include. С# - объектно-ориентированный язык, где код организован в классы. Вы можете использовать код из одного класса в другом классе в зависимости от его видимости, и вы можете разделить код из одного класса на несколько исходных файлов с помощью частичных классов. Это по сути то, как вы используете код из одного "файла" в другом. Но это не то же самое.
Ответ 2
Идиоматический способ достижения метапрограммирования в С# (помимо Generics) - с шаблонами T4 - Visual Studio и MSBuild поддерживает T4 встроенный, однако VS не поставляется с синтаксической раскраской T4 - вам понадобится сторонний add- для этого.
Чтобы продемонстрировать функциональность T4 include
, я буду использовать сценарий, требующий добавить перегрузку оператора ==
к нескольким классам одновременно без использования наследования.
Для сравнения, в С++ это будет так:
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"
}
В С# вы сделаете следующее:
- Используйте классы
partial
, чтобы вся ваша логика без метапрограммирования (то есть нормальный код С#) находилась в файле, например.Foo.cs
иBar.cs
- Создайте новый шаблон T4 в своем проекте, измените расширение выходного файла на
.cs
- Создайте второе определение
partial class
того же типа в этом файле T4 (*.tt
), хотя вы не будете выделять синтаксис С#. - Определите включенный файл:
Operators.inc.cs.t4
public static operator==(<#= typeName #> x, <#= typeName #> y) {
if( x == null && y != null ) return false;
return x.Equals( y );
}
- Добавьте его в свой шаблон 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==
(и все остальные: 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
#>
Ответ 3
В отличие от C или С++ в С# нет необходимости использовать #include для использования типов, определенных в других файлах. С# вместо этого создает разрешение на основе таких контейнеров, как классы или пространства имен. Пока оба файла включены в компиляцию, а пространство имен второго типа используется, доступно, тогда ваш класс будет доступен.
Пример:
Class1.cs
namespace Project1 {
class Class1 { ... }
}
Class2.cs
namespace Project1 {
class Class2 {
private Class1 m_field1;
..
}
}
Ответ 4
Также не забывайте, что частичные классы С# имеют некоторую функциональность, которую вы могли бы получить с помощью операторов #include.
Частичные классы позволяют разбить определение класса на несколько файлов.
Ответ 5
ознакомьтесь с с помощью
Ответ 6
Немного неясно, что вы имеете в виду. Но вы думаете о:
using MyNamespace;
Ответ 7
Вы включаете каждый файл в *.csproj, если вы используете msbuild или в командной строке csc (С# Compiler):
csc File1.cs File2.cs
http://msdn.microsoft.com/en-us/library/78f4aasd%28VS.80%29.aspx
Ответ 8
Это не совсем так, как директива С#include, но С# using statement - это то, что вы после:
using Assembly.Name;
Он работает на уровне пространства имен, а не на уровне файла. Итак, если class.cs
включает открытый класс с именем SomeClass
в пространстве имен Application.Core
, это будет выглядеть так:
using Application.Core;
Обычно это размещается в верхней части файла, в котором вы работаете, и позволял этому классу использовать SomeClass
как объект (вместе со всеми другими общедоступными классами в пространстве имен Application.Core
).
Конечно, если все классы находятся в одном и том же пространстве имен (например, Application.Core
), нет оснований вообще использовать инструкцию using
. Классы в пределах одного пространства имен могут разрешать друг друга без каких-либо деклараций.
Ответ 9
Вам нужно будет поместить содержимое class.cs в пространство имен. А затем поставьте оператор using в верхней части файла, который должен увидеть class.cs.
class.cs
namespace Class {
//class.cs stuff
}
Затем выполните следующие действия в файле, который нуждается в классе.
using Class;
Ответ 10
пример с использованием 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");
}