DynamicObject Класс
Определение
Важно!
Некоторые сведения относятся к предварительной версии продукта, в которую до выпуска могут быть внесены существенные изменения. Майкрософт не предоставляет никаких гарантий, явных или подразумеваемых, относительно приведенных здесь сведений.
Предоставляет базовый класс для указания динамического поведения в среде выполнения. Этот класс должен наследоваться; создать его экземпляр напрямую нельзя.
public ref class DynamicObject : System::Dynamic::IDynamicMetaObjectProvider
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
[System.Serializable]
public class DynamicObject : System.Dynamic.IDynamicMetaObjectProvider
type DynamicObject = class
interface IDynamicMetaObjectProvider
[<System.Serializable>]
type DynamicObject = class
interface IDynamicMetaObjectProvider
Public Class DynamicObject
Implements IDynamicMetaObjectProvider
- Наследование
-
DynamicObject
- Производный
- Атрибуты
- Реализации
Примеры
Предположим, что вы хотите предоставить альтернативный синтаксис для доступа к значениям в словаре, чтобы вместо записи sampleDictionary["Text"] = "Sample text"
(sampleDictionary("Text") = "Sample text"
в Visual Basic) можно было написать sampleDictionary.Text = "Sample text"
. Кроме того, требуется, чтобы этот синтаксис не учитывал регистр, поэтому sampleDictionary.Text
это эквивалентно sampleDictionary.text
.
В следующем примере кода демонстрируется DynamicDictionary
класс , производный DynamicObject
от класса . Класс DynamicDictionary
содержит объект Dictionary<string, object>
типа (Dictionary(Of String, Object)
в Visual Basic) для хранения пар "ключ-значение" и переопределяет TrySetMember методы и TryGetMember для поддержки нового синтаксиса. Он также предоставляет Count
свойство , которое показывает, сколько динамических свойств содержит словарь.
// The class derived from DynamicObject.
public class DynamicDictionary : DynamicObject
{
// The inner dictionary.
Dictionary<string, object> dictionary
= new Dictionary<string, object>();
// This property returns the number of elements
// in the inner dictionary.
public int Count
{
get
{
return dictionary.Count;
}
}
// If you try to get a value of a property
// not defined in the class, this method is called.
public override bool TryGetMember(
GetMemberBinder binder, out object result)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
string name = binder.Name.ToLower();
// If the property name is found in a dictionary,
// set the result parameter to the property value and return true.
// Otherwise, return false.
return dictionary.TryGetValue(name, out result);
}
// If you try to set a value of a property that is
// not defined in the class, this method is called.
public override bool TrySetMember(
SetMemberBinder binder, object value)
{
// Converting the property name to lowercase
// so that property names become case-insensitive.
dictionary[binder.Name.ToLower()] = value;
// You can always add a value to a dictionary,
// so this method always returns true.
return true;
}
}
class Program
{
static void Main(string[] args)
{
// Creating a dynamic dictionary.
dynamic person = new DynamicDictionary();
// Adding new dynamic properties.
// The TrySetMember method is called.
person.FirstName = "Ellen";
person.LastName = "Adams";
// Getting values of the dynamic properties.
// The TryGetMember method is called.
// Note that property names are case-insensitive.
Console.WriteLine(person.firstname + " " + person.lastname);
// Getting the value of the Count property.
// The TryGetMember is not called,
// because the property is defined in the class.
Console.WriteLine(
"Number of dynamic properties:" + person.Count);
// The following statement throws an exception at run time.
// There is no "address" property,
// so the TryGetMember method returns false and this causes a
// RuntimeBinderException.
// Console.WriteLine(person.address);
}
}
// This example has the following output:
// Ellen Adams
// Number of dynamic properties: 2
' The class derived from DynamicObject.
Public Class DynamicDictionary
Inherits DynamicObject
' The inner dictionary.
Dim dictionary As New Dictionary(Of String, Object)
' This property returns the number of elements
' in the inner dictionary.
ReadOnly Property Count As Integer
Get
Return dictionary.Count
End Get
End Property
' If you try to get a value of a property that is
' not defined in the class, this method is called.
Public Overrides Function TryGetMember(
ByVal binder As System.Dynamic.GetMemberBinder,
ByRef result As Object) As Boolean
' Converting the property name to lowercase
' so that property names become case-insensitive.
Dim name As String = binder.Name.ToLower()
' If the property name is found in a dictionary,
' set the result parameter to the property value and return true.
' Otherwise, return false.
Return dictionary.TryGetValue(name, result)
End Function
Public Overrides Function TrySetMember(
ByVal binder As System.Dynamic.SetMemberBinder,
ByVal value As Object) As Boolean
' Converting the property name to lowercase
' so that property names become case-insensitive.
dictionary(binder.Name.ToLower()) = value
' You can always add a value to a dictionary,
' so this method always returns true.
Return True
End Function
End Class
Sub Main()
' Creating a dynamic dictionary.
Dim person As Object = New DynamicDictionary()
' Adding new dynamic properties.
' The TrySetMember method is called.
person.FirstName = "Ellen"
person.LastName = "Adams"
' Getting values of the dynamic properties.
' The TryGetMember method is called.
' Note that property names are now case-insensitive,
' although they are case-sensitive in C#.
Console.WriteLine(person.firstname & " " & person.lastname)
' Getting the value of the Count property.
' The TryGetMember is not called,
' because the property is defined in the class.
Console.WriteLine("Number of dynamic properties:" & person.Count)
' The following statement throws an exception at run time.
' There is no "address" property,
' so the TryGetMember method returns false and this causes
' a MissingMemberException.
' Console.WriteLine(person.address)
End Sub
' This examples has the following output:
' Ellen Adams
' Number of dynamic properties: 2
Дополнительные примеры см. в статье Создание оболочек с помощью DynamicObject в блоге часто задаваемые вопросы по C#.
Комментарии
Класс DynamicObject
позволяет определить, какие операции можно выполнять с динамическими объектами и как их выполнять. Например, можно определить, что происходит при попытке получить или задать свойство объекта, вызвать метод или выполнить стандартные математические операции, такие как сложение и умножение.
Этот класс может быть полезен, если вы хотите создать более удобный протокол для библиотеки. Например, если пользователи библиотеки должны использовать такой синтаксис, как Scriptobj.SetProperty("Count", 1)
, вы можете предоставить возможность использовать гораздо более простой синтаксис, например scriptobj.Count = 1
.
Невозможно напрямую создать экземпляр DynamicObject
класса . Чтобы реализовать динамическое поведение, может потребоваться наследовать от DynamicObject
класса и переопределить необходимые методы. Например, если для задания и получения свойств требуются только операции, можно переопределить только TrySetMember методы и TryGetMember .
В C# для включения динамического поведения для экземпляров классов, производных от DynamicObject
класса , необходимо использовать dynamic
ключевое слово. Дополнительные сведения см. в разделе Использование типа dynamic.
В Visual Basic динамические операции поддерживаются поздней привязкой. Дополнительные сведения см. в статье Ранняя и поздняя привязка (Visual Basic).
В следующем примере кода показано, как создать экземпляр класса, производного от DynamicObject
класса .
public class SampleDynamicObject : DynamicObject {}
//...
dynamic sampleObject = new SampleDynamicObject ();
Public Class SampleDynamicObject
Inherits DynamicObject
'...
Dim sampleObject As Object = New SampleDynamicObject()
Вы также можете добавить собственные члены в классы, производные DynamicObject
от класса . Если класс определяет свойства, а также переопределяет TrySetMember метод, то динамическая языковая среда выполнения (DLR) сначала использует связыватель языка для поиска статического определения свойства в классе . Если такого свойства нет, DLR вызывает TrySetMember метод .
Класс DynamicObject
реализует интерфейс IDynamicMetaObjectProviderDLR , который позволяет совместно использовать экземпляры DynamicObject
класса между языками, поддерживающими модель взаимодействия DLR. Например, можно создать экземпляр класса в DynamicObject
C#, а затем передать его в функцию IronPython. Дополнительные сведения см. в статье Обзор динамической языковой среды выполнения.
Примечание
Если у вас есть простой сценарий, в котором требуется объект, который может добавлять и удалять только члены во время выполнения, но не требует определения конкретных операций и не содержит статических членов, используйте ExpandoObject класс .
Если у вас есть более сложный сценарий, в котором необходимо определить, как динамические объекты участвуют в протоколе взаимодействия, или вам нужно управлять быстрым динамическим кэшированием DLR, создайте собственную реализацию IDynamicMetaObjectProvider интерфейса.
Конструкторы
DynamicObject() |
Позволяет производным типам инициализировать новый экземпляр типа DynamicObject. |
Методы
Equals(Object) |
Определяет, равен ли указанный объект текущему объекту. (Унаследовано от Object) |
GetDynamicMemberNames() |
Возвращает перечисление имен всех динамических членов. |
GetHashCode() |
Служит хэш-функцией по умолчанию. (Унаследовано от Object) |
GetMetaObject(Expression) |
Предоставляет объект DynamicMetaObject, вызывающий динамические виртуальные методы. Объект можно инкапсулировать в другой объект DynamicMetaObject, чтобы обеспечить пользовательское поведение для отдельных действий. Данный метод поддерживает инфраструктуру среды DLR для разработчиков языков и не предназначен для непосредственного использования из кода. |
GetType() |
Возвращает объект Type для текущего экземпляра. (Унаследовано от Object) |
MemberwiseClone() |
Создает неполную копию текущего объекта Object. (Унаследовано от Object) |
ToString() |
Возвращает строку, представляющую текущий объект. (Унаследовано от Object) |
TryBinaryOperation(BinaryOperationBinder, Object, Object) |
Предоставляет реализацию для двоичных операций. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как сложение и умножение. |
TryConvert(ConvertBinder, Object) |
Предоставляет реализацию для операций преобразования типа. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для операций, преобразующих объект из одного типа в другой. |
TryCreateInstance(CreateInstanceBinder, Object[], Object) |
Предоставляет реализацию для операций, инициализирующих новый экземпляр динамического объекта. Этот метод не предназначен для использования в C# или Visual Basic. |
TryDeleteIndex(DeleteIndexBinder, Object[]) |
Предоставляет реализацию для операций, удаляющих объект по индексу. Этот метод не предназначен для использования в C# или Visual Basic. |
TryDeleteMember(DeleteMemberBinder) |
Предоставляет реализацию для операций, удаляющих элемент объекта. Этот метод не предназначен для использования в C# или Visual Basic. |
TryGetIndex(GetIndexBinder, Object[], Object) |
Предоставляет реализацию для операций, получающих значение по индексу. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для операций индексации. |
TryGetMember(GetMemberBinder, Object) |
Предоставляет реализацию для операций, получающих значения членов. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как получение значения свойства. |
TryInvoke(InvokeBinder, Object[], Object) |
Предоставляет реализацию для операций, вызывающих объект. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как вызов объекта или делегата. |
TryInvokeMember(InvokeMemberBinder, Object[], Object) |
Предоставляет реализацию для операций, вызывающих член. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как вызов метода. |
TrySetIndex(SetIndexBinder, Object[], Object) |
Предоставляет реализацию для операций, задающих значение по индексу. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для операций, осуществляющих доступ к объектам по заданному индексу. |
TrySetMember(SetMemberBinder, Object) |
Предоставляет реализацию для операций, задающих значения членов. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как задание значения свойства. |
TryUnaryOperation(UnaryOperationBinder, Object) |
Предоставляет реализацию для унарных операций. Классы, производные от класса DynamicObject, могут переопределять этот метод, чтобы задать динамическое поведение для таких операций, как вычитание, увеличение или уменьшение. |