logo search
CSharp_Prog_Guide

Использование атрибутов

Атрибуты могут быть размещены в большинстве описаний, хотя определенный атрибут может ограничить типы описаний, в которых он допустим. Синтаксически атрибут указывается путем размещения его имени, заключенного в квадратные скобки, в начале объявления сущности, к которой он применяется. Например, объявление метода с атрибутом DllImport выглядит следующим образом.

---

Многие атрибуты имеют параметры, которые могут быть либо позиционными, неименованными, либо именованными. Позиционные параметры следует указывать в определенном порядке, их нельзя опускать; именованные параметры являются необязательными и могут быть указаны в любой последовательности. Сначала указываются позиционные параметры. Например, следующие три атрибута являются эквивалентными.

----

Первый параметр — имя библиотеки DLL — является позиционным и всегда стоит на первом месте; остальные являются именованными. В этом случае оба именованных параметра по умолчанию имеют значение "false" и могут быть пропущены. Сведения о заданных по умолчанию значениях параметров см. в документации по отдельному атрибуту.

В описании можно разместить несколько атрибутов — либо по отдельности, либо в одном наборе скобок.

-------

Для заданной сущности некоторые атрибуты можно указать несколько раз. Примером такого многократно используемого атрибута является Conditional.

----

Примечание.

Чтобы отличать атрибуты от других элементов платформы .NET Framework, используется соглашение, по которому все имена атрибутов заканчиваются словом "Attribute" ("атрибут"). Однако нет необходимости указывать суффикс атрибута при его использовании в коде. Например, [DllImport] эквивалентен [DllImportAttribute], однако DllImportAttribute является фактическим именем атрибута в платформе .NET Framework.

How to: Create a C/C++ Union Using Attributes

By using attributes you can customize how structs are laid out in memory. For example, you can create what is known as a union in C/C++ by using the StructLayout(LayoutKind.Explicit) and FieldOffset attributes.

Example

In this code segment, all of the fields of TestUnion start at the same location in memory.

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]

struct TestUnion

{

[System.Runtime.InteropServices.FieldOffset(0)]

public int i;

[System.Runtime.InteropServices.FieldOffset(0)]

public double d;

[System.Runtime.InteropServices.FieldOffset(0)]

public char c;

[System.Runtime.InteropServices.FieldOffset(0)]

public byte b;

}

The following is another example where fields start at different explicitly set locations.

[System.Runtime.InteropServices.StructLayout(LayoutKind.Explicit)]

struct TestExplicit

{

[System.Runtime.InteropServices.FieldOffset(0)]

public long lg;

[System.Runtime.InteropServices.FieldOffset(0)]

public int i1;

[System.Runtime.InteropServices.FieldOffset(4)]

public int i2;

[System.Runtime.InteropServices.FieldOffset(8)]

public double d;

[System.Runtime.InteropServices.FieldOffset(12)]

public char c;

[System.Runtime.InteropServices.FieldOffset(14)]

public byte b;

}

The two int fields, i1 and i2, share the same memory locations as lg. This sort of control over struct layout is useful when using platform invocation.

Создание объединения C/C++ с помощью атрибутов

Использование атрибутов позволяет настраивать расположение структур в памяти. Например, можно создать так называемое объединение в языках C/C++ с помощью атрибутов StructLayout(LayoutKind.Explicit) и FieldOffset.

Пример

В этом сегменте кода все поля объединения TestUnion начинаются с одного адреса в памяти.

-----

Ниже приведен еще один пример, в котором поля начинаются с разных явно заданных адресов.

-----

Два поля int, i1 и i2, совместно используют те же адреса в памяти, что и lg. Такое управление расположением структуры полезно при использовании вызова неуправляемого кода.

Common Attributes

This section describes the attributes that are most commonly used in C# programs.

Conditional

Makes the execution of a method dependent on a preprocessing identifier. The Conditional attribute is an alias for ConditionalAttribute, and can be applied to a method or an attribute class.

In this example, Conditional is applied to a method to enable or disable the display of program-specific diagnostic information:

#define TRACE_ON

using System;

using System.Diagnostics;

public class Trace

{

[Conditional("TRACE_ON")]

public static void Msg(string msg)

{

Console.WriteLine(msg);

}

}

public class ProgramClass

{

static void Main()

{

Trace.Msg("Now in Main...");

Console.WriteLine("Done.");

}

}

If the TRACE_ON identifier is not defined, no trace output will be displayed.

The Conditional attribute is often used with the DEBUG identifier to enable trace and logging features for debug builds but not in release builds, like this:

[Conditional("DEBUG")]

static void DebugMethod()

{

}