전 처리기의 C # 매크로 정의
C #은 전 처리기 문을 사용하여 C 프로그래밍 언어에서 수행되는 것처럼 매크로를 정의 할 수 있습니까? 다음과 같이 반복되는 특정 문을 정기적으로 입력하는 것을 단순화하고 싶습니다.
Console.WriteLine("foo");
아니요, C #은 C와 같은 전 처리기 매크로를 지원하지 않습니다 . 반면에 Visual Studio에는 스 니펫이 있습니다. Visual Studio의 코드 조각은 IDE의 기능이며 컴파일시 코드에서 전처리기에 의해 대체되지 않고 편집기에서 확장됩니다.
mcpp와 같은 C 전처리기를 사용하여 .csproj 파일에 리깅 할 수 있습니다. 그런 다음 Compile에서 Preprocess로 또는 호출하는 모든 소스 파일에 대한 "빌드 작업"을 변경합니다. 다음과 같이 BeforBuild 를 .csproj에 추가 하십시오.
<Target Name="BeforeBuild" Inputs="@(Preprocess)" Outputs="@(Preprocess->'%(Filename)_P.cs')">
<Exec Command="..\Bin\cpp.exe @(Preprocess) -P -o %(RelativeDir)%(Filename)_P.cs" />
<CreateItem Include="@(Preprocess->'%(RelativeDir)%(Filename)_P.cs')">
<Output TaskParameter="Include" ItemName="Compile" />
</CreateItem>
적어도 하나의 파일 (텍스트 편집기에서)에서 Compile to Preprocess를 수동으로 변경해야 할 수 있습니다. 그러면 Visual Studio에서 "Preprocess"옵션을 선택할 수 있습니다.
매크로가 많이 남용되고 오용된다는 것을 알고 있지만 완전히 제거하는 것은 나쁘지는 않더라도 똑같이 나쁩니다. 매크로 사용의 전형적인 예는 NotifyPropertyChanged 입니다. 이 코드를 수천 번 손으로 다시 작성해야했던 모든 프로그래머는 매크로 없이는 얼마나 고통 스러운지 알고 있습니다.
나는 이것을 피하기 위해 사용합니다 Console.WriteLine(...)
.
public static void Cout(this string str, params object[] args) {
Console.WriteLine(str, args);
}
다음을 사용할 수 있습니다.
"line 1".Cout();
"This {0} is an {1}".Cout("sentence", "example");
간결하고 펑키합니다.
매크로를 작성할 수는 없지만 예제와 같은 것을 단순화 할 때 C # 6.0은 이제 정적 사용을 제공합니다. 다음은 Martin Pernica가 미디엄 기사 에서 제시 한 예입니다 .
using static System.Console; // Note the static keyword
namespace CoolCSharp6Features
{
public class Program
{
public static int Main(string[] args)
{
WriteLine("Hellow World without Console class name prefix!");
return 0;
}
}
}
C #의 C 스타일 매크로에 직접 해당하는 것은 없지만 / / pragma inline
가 있거나없는 d 정적 메서드 가 가장 가까운 방법입니다.#if
#elseif
#else
/// <summary>
/// Prints a message when in debug mode
/// </summary>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Log(object message) {
#if DEBUG
Console.WriteLine(message);
#endif
}
/// <summary>
/// Prints a formatted message when in debug mode
/// </summary>
/// <param name="format">A composite format string</param>
/// <param name="args">An array of objects to write using format</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void Log(string format, params object[] args) {
#if DEBUG
Console.WriteLine(format, args);
#endif
}
/// <summary>
/// Computes the square of a number
/// </summary>
/// <param name="x">The value</param>
/// <returns>x * x</returns>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static double Square(double x) {
return x * x;
}
/// <summary>
/// Wipes a region of memory
/// </summary>
/// <param name="buffer">The buffer</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void ClearBuffer(ref byte[] buffer) {
ClearBuffer(ref buffer, 0, buffer.Length);
}
/// <summary>
/// Wipes a region of memory
/// </summary>
/// <param name="buffer">The buffer</param>
/// <param name="offset">Start index</param>
/// <param name="length">Number of bytes to clear</param>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static unsafe void ClearBuffer(ref byte[] buffer, int offset, int length) {
fixed(byte* ptrBuffer = &buffer[offset]) {
for(int i = 0; i < length; ++i) {
*(ptrBuffer + i) = 0;
}
}
}
이것은 매크로처럼 완벽하게 작동하지만 약간의 단점 inline
이 있습니다. d 로 표시된 메서드는 다른 "일반"메서드와 마찬가지로 어셈블리의 리플렉션 부분에 복사됩니다.
다행히 C #에는 C / C ++ 스타일의 전처리 기가 없습니다. 조건부 컴파일과 pragma (그리고 내가 기억할 수없는 다른 것) 만 지원됩니다. 불행히도 C #에는 메타 프로그래밍 기능이 없습니다 ( 실제로 귀하의 질문과 어느 정도 관련 이 있을 수 있습니다 ).
클래스에서 C 매크로를 C # 정적 메서드로 전환합니다.
다음과 같이 확장 기능을 작성하는 것이 좋습니다.
public static class WriteToConsoleExtension
{
// Extension to all types
public static void WriteToConsole(this object instance,
string format,
params object[] data)
{
Console.WriteLine(format, data);
}
}
class Program
{
static void Main(string[] args)
{
Program p = new Program();
// Usage of extension
p.WriteToConsole("Test {0}, {1}", DateTime.Now, 1);
}
}
이것이 도움이되기를 바랍니다 (너무 늦지 않았습니다 :))
Since C# 7.0 supports using static
directive and Local functions you don't need preprocessor macros for most cases.
참고URL : https://stackoverflow.com/questions/709463/c-sharp-macro-definitions-in-preprocessor
'developer tip' 카테고리의 다른 글
onKeyDown 이벤트가 React의 div에서 작동하지 않습니다. (0) | 2020.11.27 |
---|---|
LINQ to XML에서 요소의 전체 복사를 수행하려면 어떻게합니까? (0) | 2020.11.27 |
Python에서 문자열 대신 datetime으로 sqlite에서 datetime을 다시 읽는 방법은 무엇입니까? (0) | 2020.11.27 |
ITextSharp HTML을 PDF로? (0) | 2020.11.27 |
C # : Function in Function 가능? (0) | 2020.11.27 |