Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp_Prog_Guide.doc
Скачиваний:
18
Добавлен:
16.11.2019
Размер:
6.22 Mб
Скачать

Общие сведения об атрибутах

Атрибуты имеют следующие параметры.

  • Атрибуты добавляют в программу метаданные. Метаданные — это сведения, встроенные в программу, например инструкции компилятора или описания данных.

  • Программа может проверить собственные метаданные с помощью отражения.

  • Атрибуты обычно используются при взаимодействии с COM.

Using Attributes

Attributes can be placed on most any declaration, though a specific attribute might restrict the types of declarations on which it is valid. Syntactically, an attribute is specified by placing the name of the attribute, enclosed in square brackets, in front of the declaration of the entity to which it applies. For example, a method with the attribute DllImport is declared like this:

[System.Runtime.InteropServices.DllImport("user32.dll")]

extern static void SampleMethod();

Many attributes have parameters, which can be either positional, unnamed, or named. Any positional parameters must be specified in a certain order and cannot be omitted; named parameters are optional and can be specified in any order. Positional parameters are specified first. For example, these three attributes are equivalent:

[DllImport("user32.dll")]

[DllImport("user32.dll", SetLastError=false, ExactSpelling=false)]

[DllImport("user32.dll", ExactSpelling=false, SetLastError=false)]

The first parameter, the DLL name, is positional and always comes first; the others are named. In this case, both named parameters default to false, so they can be omitted. Refer to the individual attribute's documentation for information on default parameter values.

More than one attribute can be placed on a declaration, either separately or within the same set of brackets:

void MethodA([In][Out] ref double x) { }

void MethodB([Out][In] ref double x) { }

void MethodC([In, Out] ref double x) { }

Some attributes can be specified more than once for a given entity. An example of such a multiuse attribute is Conditional:

[Conditional("DEBUG"), Conditional("TEST1")]

void TraceMethod()

{

// ...

}

Note:

By convention, all attribute names end with the word "Attribute" to distinguish them from other items in the .NET Framework. However, you do not need to specify the attribute suffix when using attributes in code. For example, [DllImport] is equivalent to [DllImportAttribute], but DllImportAttribute is the attribute's actual name in the .NET Framework.

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

Атрибуты могут быть размещены в большинстве описаний, хотя определенный атрибут может ограничить типы описаний, в которых он допустим. Синтаксически атрибут указывается путем размещения его имени, заключенного в квадратные скобки, в начале объявления сущности, к которой он применяется. Например, объявление метода с атрибутом 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()

{

}