I have a situation where i want to add LinePragmas to CodeDom objects. But some code dom objects have the LinePragma property and some don't.
我有一种情况,我想将LinePragmas添加到CodeDom对象。但是一些代码dom对象具有LinePragma属性,而有些则没有。
So I'm wondering if it's possible to use the dynamic keyword to detect if the property exists on the object (without throwing an exception) and if it does then add the pragma. Here is my current method:
所以我想知道是否可以使用dynamic关键字来检测对象上是否存在属性(不抛出异常),如果有,则添加pragma。这是我目前的方法:
public static T SetSource<T>(this T codeObject, INode sourceNode)
where T : CodeObject
{
codeObject.UserData["Node"] = sourceNode.Source;
dynamic dynamicCodeObject = codeObject;
// How can I not throw an exception here?
if (dynamicCodeObject.LinePragma != null)
{
dynamicCodeObject.LinePragma = new CodeLinePragma(
sourceNode.Source.Path.AbsoluteUri,
sourceNode.Source.StartLine);
}
return codeObject;
}
UPDATE: The solution I went with was to add an extension method called Exists(). I wrote a blog post about it here: Member Exists Dynamic C# 4.0
更新:我使用的解决方案是添加一个名为Exists()的扩展方法。我在这里写了一篇关于它的博客文章:成员存在动态C#4.0
The jist was to create an extension method that returns an object that implements DynamicObject's TryGetMember. It uses reflection to then return true or false. Which allows you to write code like this:
jist是创建一个扩展方法,返回一个实现DynamicObject的TryGetMember的对象。它使用反射然后返回true或false。这允许你编写这样的代码:
object instance = new { Foo = "Hello World!" };
if (instance.Reflection().Exists().Foo)
{
string value = instance.Reflection().Call().Foo;
Console.WriteLine(value);
}
6 个解决方案
#1
You can detect if an object has a property without having to use the dynamic features of C# 4.0 - instead using the reflection features that have been around for a while (I know at least .NET 2.0, not sure about < 2.0)
您可以检测对象是否具有属性而无需使用C#4.0的动态功能 - 而是使用已经存在一段时间的反射功能(我至少知道.NET 2.0,不确定<2.0)
PropertyInfo info = codeObject.getType().GetProperty(
"LinePragma",
BindingFlags.Public | BindingFlags.Instance
)
If it the object does not have the property, then GetProperty() will return null. You can do similar for fields ( GetField() ) and methods ( GetMethod() ).
如果对象没有该属性,则GetProperty()将返回null。您可以对字段(GetField())和方法(GetMethod())执行类似操作。
Not only that, but once you have the PropertyInfo, you can use it directly to do your set:
不仅如此,一旦你拥有PropertyInfo,你可以直接使用它来做你的集合:
info.SetValue(codeObject, new CodeLinePragma(), null);
If you're not sure whether the property has a set method, you could take the even safer route:
如果您不确定该属性是否具有set方法,您可以采取更安全的路线:
MethodInfo method = info.GetSetMethod();
if(method != null)
method.Invoke(codeObject, new object[]{ new CodeLinePragma() });
This also gives you the added benefit of being a little more performant over the lookup overhead of the dynamic call (can't find a reference for that statement, so I'll just float it out there).
这也为您提供了额外的好处,即在动态调用的查找开销上更加高效(无法找到该语句的引用,所以我只是将它浮出去)。
I suppose that doesn't answer your question directly, but rather is an alternative solution to accomplish the same goal. I haven't actually used #4.0 features yet (even though I'm a huge fan of the dynamic typing available in Ruby). It certainly not as clean/readable as the dynamic solution, but if you don't want to throw an exception it may be the way to go.
我想这不是直接回答你的问题,而是实现同一目标的另一种解决方案。我还没有真正使用#4.0功能(尽管我是Ruby中动态类型的忠实粉丝)。它当然不像动态解决方案那样干净/可读,但如果你不想抛出异常,它可能就是这样。
EDIT: as @arbiter points out, "This is valid only for native .net dynamic objects. This will not work for example for IDispatch."
编辑:正如@arbiter所指出的,“这仅对本机.net动态对象有效。例如,对于IDispatch,这不起作用。”
#2
I just spent almost an hour searching for ways to get some kind of ruby-esque "RespondTo" Method on dynamic. There certainly isn't an easy answer, but I haven't given up yet.
我花了将近一个小时的时间来寻找获得某种红宝石式“RespondTo”方法的方法。肯定没有一个简单的答案,但我还没有放弃。
The point made on reflection should be the thing to try.
反思的观点应该是尝试的。
With dynamic, the only thing I get so far is an extension method that treats your object as dynamic. If it works, it works, if not it silently fails...
使用动态,我到目前为止唯一能做的就是将对象视为动态的扩展方法。如果它有效,它可以工作,如果没有它默默地失败...
public static void Dynamight<T>(this T target, Action<dynamic> action)
{
dynamic d = target;
try
{
action(d);
}
catch (RuntimeBinderException)
{
//That was that, didn't work out
}
}
Then you can do...
然后你可以......
string h = "Hello";
h.Dynamight(d => Console.WriteLine(d.Length)); //Prints out 5
h.Dynamight(d => d.Foo()); //Nothing happens
Update:
Since I am getting downvotes and what-have-you let me be more concise than the subtle naming of the extension method: It is dynamite (Geddit?)! Gobbling exceptions and doing nothing is bad. This is no production code, but a version 1 of a spike of a proof of concept. I keep forgetting that you can't be subtle on a multi-thousands forum like *. Mea culpa.
因为我得到了downvotes和what-have-you让你比扩展方法的微妙命名更简洁:它是炸药(Geddit?)!吞噬异常并无所作为是不好的。这不是生产代码,而是概念证明的第1版。我一直忘记你不能在像*这样的数千个论坛上微妙。 Mea culpa。
#3
18 months later ... it seems like what you really wanted is there now that it's released. It's the TryGetMember, TryGetValue, etc... actually, probably TrySetMember, specifically.
18个月后......看起来你真正想要的就是它现在已经发布了。这是TryGetMember,TryGetValue等......实际上,可能是TrySetMember,特别是。
http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject_members.aspx
#4
I'm going to chime in and say static typing would avoid this problem.
我要打电话说静态打字会避免这个问题。
This is a candidate for an abstract method with overriding.
这是覆盖抽象方法的候选者。
#5
Think about it: since the target class can provide its own implementation for the member lookup and invocation for non-existing members (by implementing IDynamicObject or subclassing DynamicObject) the only way to verify if a member exists is to invoke it and see whether the object handles it or throws an exception.
想一想:由于目标类可以为成员查找和调用非现有成员提供自己的实现(通过实现IDynamicObject或子类化DynamicObject)验证成员是否存在的唯一方法是调用它并查看对象是否存在处理它或抛出异常。
Once again, handling of non-existing members is DYNAMIC!
再一次,对现有成员的处理是动态的!
--EDIT--
If you control object creation, you could subclass the class and implement IDynamicObject to signal your other class that method does not exist.
如果您控制对象创建,则可以对该类进行子类化并实现IDynamicObject,以向您的其他类发出该方法不存在的信号。
It's unfair to downvote the answer if it points out the truth -- i.e. that there's no and cannot be a reliable way to check member existence in dynamic dispatch environment other than invoking the member.
如果它指出了真相,那么对于回答这个问题是不公平的 - 即除了调用成员之外,没有也不可能是在动态调度环境中检查成员存在的可靠方法。
#6
using System.Collections.Generic;
using System.Linq.Expressions;
namespace System.Dynamic
{
//
// Summary:
// Provides a base class for specifying dynamic behavior at run time. This class
// must be inherited from; you cannot instantiate it directly.
public class DynamicObject : IDynamicMetaObjectProvider
{
//
// Summary:
// Enables derived types to initialize a new instance of the System.Dynamic.DynamicObject
// type.
protected DynamicObject();
//
// Summary:
// Returns the enumeration of all dynamic member names.
//
// Returns:
// A sequence that contains dynamic member names.
public virtual IEnumerable<string> GetDynamicMemberNames();
//
// Summary:
// Provides a System.Dynamic.DynamicMetaObject that dispatches to the dynamic virtual
// methods. The object can be encapsulated inside another System.Dynamic.DynamicMetaObject
// to provide custom behavior for individual actions. This method supports the Dynamic
// Language Runtime infrastructure for language implementers and it is not intended
// to be used directly from your code.
//
// Parameters:
// parameter:
// The expression that represents System.Dynamic.DynamicMetaObject to dispatch to
// the dynamic virtual methods.
//
// Returns:
// An object of the System.Dynamic.DynamicMetaObject type.
public virtual DynamicMetaObject GetMetaObject(Expression parameter);
//
// Summary:
// Provides implementation for binary operations. Classes derived from the System.Dynamic.DynamicObject
// class can override this method to specify dynamic behavior for operations such
// as addition and multiplication.
//
// Parameters:
// binder:
// Provides information about the binary operation. The binder.Operation property
// returns an System.Linq.Expressions.ExpressionType object. For example, for the
// sum = first + second statement, where first and second are derived from the DynamicObject
// class, binder.Operation returns ExpressionType.Add.
//
// arg:
// The right operand for the binary operation. For example, for the sum = first
// + second statement, where first and second are derived from the DynamicObject
// class, arg is equal to second.
//
// result:
// The result of the binary operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result);
//
// Summary:
// Provides implementation for type conversion operations. Classes derived from
// the System.Dynamic.DynamicObject class can override this method to specify dynamic
// behavior for operations that convert an object from one type to another.
//
// Parameters:
// binder:
// Provides information about the conversion operation. The binder.Type property
// provides the type to which the object must be converted. For example, for the
// statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic),
// where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Type returns the System.String type. The binder.Explicit property
// provides information about the kind of conversion that occurs. It returns true
// for explicit conversion and false for implicit conversion.
//
// result:
// The result of the type conversion operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryConvert(ConvertBinder binder, out object result);
//
// Summary:
// Provides the implementation for operations that initialize a new instance of
// a dynamic object. This method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the initialization operation.
//
// args:
// The arguments that are passed to the object during initialization. For example,
// for the new SampleType(100) operation, where SampleType is the type derived from
// the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the initialization.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that delete an object by index. This
// method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the deletion.
//
// indexes:
// The indexes to be deleted.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes);
//
// Summary:
// Provides the implementation for operations that delete an object member. This
// method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the deletion.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryDeleteMember(DeleteMemberBinder binder);
//
// Summary:
// Provides the implementation for operations that get a value by index. Classes
// derived from the System.Dynamic.DynamicObject class can override this method
// to specify dynamic behavior for indexing operations.
//
// Parameters:
// binder:
// Provides information about the operation.
//
// indexes:
// The indexes that are used in the operation. For example, for the sampleObject[3]
// operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived
// from the DynamicObject class, indexes[0] is equal to 3.
//
// result:
// The result of the index operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a run-time exception is thrown.)
public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result);
//
// Summary:
// Provides the implementation for operations that get member values. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as getting a value for a property.
//
// Parameters:
// binder:
// Provides information about the object that called the dynamic operation. The
// binder.Name property provides the name of the member on which the dynamic operation
// is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty)
// statement, where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies
// whether the member name is case-sensitive.
//
// result:
// The result of the get operation. For example, if the method is called for a property,
// you can assign the property value to result.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a run-time exception is thrown.)
public virtual bool TryGetMember(GetMemberBinder binder, out object result);
//
// Summary:
// Provides the implementation for operations that invoke an object. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as invoking an object or a delegate.
//
// Parameters:
// binder:
// Provides information about the invoke operation.
//
// args:
// The arguments that are passed to the object during the invoke operation. For
// example, for the sampleObject(100) operation, where sampleObject is derived from
// the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the object invocation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.
public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that invoke a member. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as calling a method.
//
// Parameters:
// binder:
// Provides information about the dynamic operation. The binder.Name property provides
// the name of the member on which the dynamic operation is performed. For example,
// for the statement sampleObject.SampleMethod(100), where sampleObject is an instance
// of the class derived from the System.Dynamic.DynamicObject class, binder.Name
// returns "SampleMethod". The binder.IgnoreCase property specifies whether the
// member name is case-sensitive.
//
// args:
// The arguments that are passed to the object member during the invoke operation.
// For example, for the statement sampleObject.SampleMethod(100), where sampleObject
// is derived from the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the member invocation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that set a value by index. Classes
// derived from the System.Dynamic.DynamicObject class can override this method
// to specify dynamic behavior for operations that access objects by a specified
// index.
//
// Parameters:
// binder:
// Provides information about the operation.
//
// indexes:
// The indexes that are used in the operation. For example, for the sampleObject[3]
// = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject
// is derived from the System.Dynamic.DynamicObject class, indexes[0] is equal to
// 3.
//
// value:
// The value to set to the object that has the specified index. For example, for
// the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic),
// where sampleObject is derived from the System.Dynamic.DynamicObject class, value
// is equal to 10.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.
public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value);
//
// Summary:
// Provides the implementation for operations that set member values. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as setting a value for a property.
//
// Parameters:
// binder:
// Provides information about the object that called the dynamic operation. The
// binder.Name property provides the name of the member to which the value is being
// assigned. For example, for the statement sampleObject.SampleProperty = "Test",
// where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies
// whether the member name is case-sensitive.
//
// value:
// The value to set to the member. For example, for sampleObject.SampleProperty
// = "Test", where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, the value is "Test".
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TrySetMember(SetMemberBinder binder, object value);
//
// Summary:
// Provides implementation for unary operations. Classes derived from the System.Dynamic.DynamicObject
// class can override this method to specify dynamic behavior for operations such
// as negation, increment, or decrement.
//
// Parameters:
// binder:
// Provides information about the unary operation. The binder.Operation property
// returns an System.Linq.Expressions.ExpressionType object. For example, for the
// negativeNumber = -number statement, where number is derived from the DynamicObject
// class, binder.Operation returns "Negate".
//
// result:
// The result of the unary operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryUnaryOperation(UnaryOperationBinder binder, out object result);
}`enter code here`
}
#1
You can detect if an object has a property without having to use the dynamic features of C# 4.0 - instead using the reflection features that have been around for a while (I know at least .NET 2.0, not sure about < 2.0)
您可以检测对象是否具有属性而无需使用C#4.0的动态功能 - 而是使用已经存在一段时间的反射功能(我至少知道.NET 2.0,不确定<2.0)
PropertyInfo info = codeObject.getType().GetProperty(
"LinePragma",
BindingFlags.Public | BindingFlags.Instance
)
If it the object does not have the property, then GetProperty() will return null. You can do similar for fields ( GetField() ) and methods ( GetMethod() ).
如果对象没有该属性,则GetProperty()将返回null。您可以对字段(GetField())和方法(GetMethod())执行类似操作。
Not only that, but once you have the PropertyInfo, you can use it directly to do your set:
不仅如此,一旦你拥有PropertyInfo,你可以直接使用它来做你的集合:
info.SetValue(codeObject, new CodeLinePragma(), null);
If you're not sure whether the property has a set method, you could take the even safer route:
如果您不确定该属性是否具有set方法,您可以采取更安全的路线:
MethodInfo method = info.GetSetMethod();
if(method != null)
method.Invoke(codeObject, new object[]{ new CodeLinePragma() });
This also gives you the added benefit of being a little more performant over the lookup overhead of the dynamic call (can't find a reference for that statement, so I'll just float it out there).
这也为您提供了额外的好处,即在动态调用的查找开销上更加高效(无法找到该语句的引用,所以我只是将它浮出去)。
I suppose that doesn't answer your question directly, but rather is an alternative solution to accomplish the same goal. I haven't actually used #4.0 features yet (even though I'm a huge fan of the dynamic typing available in Ruby). It certainly not as clean/readable as the dynamic solution, but if you don't want to throw an exception it may be the way to go.
我想这不是直接回答你的问题,而是实现同一目标的另一种解决方案。我还没有真正使用#4.0功能(尽管我是Ruby中动态类型的忠实粉丝)。它当然不像动态解决方案那样干净/可读,但如果你不想抛出异常,它可能就是这样。
EDIT: as @arbiter points out, "This is valid only for native .net dynamic objects. This will not work for example for IDispatch."
编辑:正如@arbiter所指出的,“这仅对本机.net动态对象有效。例如,对于IDispatch,这不起作用。”
#2
I just spent almost an hour searching for ways to get some kind of ruby-esque "RespondTo" Method on dynamic. There certainly isn't an easy answer, but I haven't given up yet.
我花了将近一个小时的时间来寻找获得某种红宝石式“RespondTo”方法的方法。肯定没有一个简单的答案,但我还没有放弃。
The point made on reflection should be the thing to try.
反思的观点应该是尝试的。
With dynamic, the only thing I get so far is an extension method that treats your object as dynamic. If it works, it works, if not it silently fails...
使用动态,我到目前为止唯一能做的就是将对象视为动态的扩展方法。如果它有效,它可以工作,如果没有它默默地失败...
public static void Dynamight<T>(this T target, Action<dynamic> action)
{
dynamic d = target;
try
{
action(d);
}
catch (RuntimeBinderException)
{
//That was that, didn't work out
}
}
Then you can do...
然后你可以......
string h = "Hello";
h.Dynamight(d => Console.WriteLine(d.Length)); //Prints out 5
h.Dynamight(d => d.Foo()); //Nothing happens
Update:
Since I am getting downvotes and what-have-you let me be more concise than the subtle naming of the extension method: It is dynamite (Geddit?)! Gobbling exceptions and doing nothing is bad. This is no production code, but a version 1 of a spike of a proof of concept. I keep forgetting that you can't be subtle on a multi-thousands forum like *. Mea culpa.
因为我得到了downvotes和what-have-you让你比扩展方法的微妙命名更简洁:它是炸药(Geddit?)!吞噬异常并无所作为是不好的。这不是生产代码,而是概念证明的第1版。我一直忘记你不能在像*这样的数千个论坛上微妙。 Mea culpa。
#3
18 months later ... it seems like what you really wanted is there now that it's released. It's the TryGetMember, TryGetValue, etc... actually, probably TrySetMember, specifically.
18个月后......看起来你真正想要的就是它现在已经发布了。这是TryGetMember,TryGetValue等......实际上,可能是TrySetMember,特别是。
http://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject_members.aspx
#4
I'm going to chime in and say static typing would avoid this problem.
我要打电话说静态打字会避免这个问题。
This is a candidate for an abstract method with overriding.
这是覆盖抽象方法的候选者。
#5
Think about it: since the target class can provide its own implementation for the member lookup and invocation for non-existing members (by implementing IDynamicObject or subclassing DynamicObject) the only way to verify if a member exists is to invoke it and see whether the object handles it or throws an exception.
想一想:由于目标类可以为成员查找和调用非现有成员提供自己的实现(通过实现IDynamicObject或子类化DynamicObject)验证成员是否存在的唯一方法是调用它并查看对象是否存在处理它或抛出异常。
Once again, handling of non-existing members is DYNAMIC!
再一次,对现有成员的处理是动态的!
--EDIT--
If you control object creation, you could subclass the class and implement IDynamicObject to signal your other class that method does not exist.
如果您控制对象创建,则可以对该类进行子类化并实现IDynamicObject,以向您的其他类发出该方法不存在的信号。
It's unfair to downvote the answer if it points out the truth -- i.e. that there's no and cannot be a reliable way to check member existence in dynamic dispatch environment other than invoking the member.
如果它指出了真相,那么对于回答这个问题是不公平的 - 即除了调用成员之外,没有也不可能是在动态调度环境中检查成员存在的可靠方法。
#6
using System.Collections.Generic;
using System.Linq.Expressions;
namespace System.Dynamic
{
//
// Summary:
// Provides a base class for specifying dynamic behavior at run time. This class
// must be inherited from; you cannot instantiate it directly.
public class DynamicObject : IDynamicMetaObjectProvider
{
//
// Summary:
// Enables derived types to initialize a new instance of the System.Dynamic.DynamicObject
// type.
protected DynamicObject();
//
// Summary:
// Returns the enumeration of all dynamic member names.
//
// Returns:
// A sequence that contains dynamic member names.
public virtual IEnumerable<string> GetDynamicMemberNames();
//
// Summary:
// Provides a System.Dynamic.DynamicMetaObject that dispatches to the dynamic virtual
// methods. The object can be encapsulated inside another System.Dynamic.DynamicMetaObject
// to provide custom behavior for individual actions. This method supports the Dynamic
// Language Runtime infrastructure for language implementers and it is not intended
// to be used directly from your code.
//
// Parameters:
// parameter:
// The expression that represents System.Dynamic.DynamicMetaObject to dispatch to
// the dynamic virtual methods.
//
// Returns:
// An object of the System.Dynamic.DynamicMetaObject type.
public virtual DynamicMetaObject GetMetaObject(Expression parameter);
//
// Summary:
// Provides implementation for binary operations. Classes derived from the System.Dynamic.DynamicObject
// class can override this method to specify dynamic behavior for operations such
// as addition and multiplication.
//
// Parameters:
// binder:
// Provides information about the binary operation. The binder.Operation property
// returns an System.Linq.Expressions.ExpressionType object. For example, for the
// sum = first + second statement, where first and second are derived from the DynamicObject
// class, binder.Operation returns ExpressionType.Add.
//
// arg:
// The right operand for the binary operation. For example, for the sum = first
// + second statement, where first and second are derived from the DynamicObject
// class, arg is equal to second.
//
// result:
// The result of the binary operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryBinaryOperation(BinaryOperationBinder binder, object arg, out object result);
//
// Summary:
// Provides implementation for type conversion operations. Classes derived from
// the System.Dynamic.DynamicObject class can override this method to specify dynamic
// behavior for operations that convert an object from one type to another.
//
// Parameters:
// binder:
// Provides information about the conversion operation. The binder.Type property
// provides the type to which the object must be converted. For example, for the
// statement (String)sampleObject in C# (CType(sampleObject, Type) in Visual Basic),
// where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Type returns the System.String type. The binder.Explicit property
// provides information about the kind of conversion that occurs. It returns true
// for explicit conversion and false for implicit conversion.
//
// result:
// The result of the type conversion operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryConvert(ConvertBinder binder, out object result);
//
// Summary:
// Provides the implementation for operations that initialize a new instance of
// a dynamic object. This method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the initialization operation.
//
// args:
// The arguments that are passed to the object during initialization. For example,
// for the new SampleType(100) operation, where SampleType is the type derived from
// the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the initialization.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryCreateInstance(CreateInstanceBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that delete an object by index. This
// method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the deletion.
//
// indexes:
// The indexes to be deleted.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryDeleteIndex(DeleteIndexBinder binder, object[] indexes);
//
// Summary:
// Provides the implementation for operations that delete an object member. This
// method is not intended for use in C# or Visual Basic.
//
// Parameters:
// binder:
// Provides information about the deletion.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryDeleteMember(DeleteMemberBinder binder);
//
// Summary:
// Provides the implementation for operations that get a value by index. Classes
// derived from the System.Dynamic.DynamicObject class can override this method
// to specify dynamic behavior for indexing operations.
//
// Parameters:
// binder:
// Provides information about the operation.
//
// indexes:
// The indexes that are used in the operation. For example, for the sampleObject[3]
// operation in C# (sampleObject(3) in Visual Basic), where sampleObject is derived
// from the DynamicObject class, indexes[0] is equal to 3.
//
// result:
// The result of the index operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a run-time exception is thrown.)
public virtual bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result);
//
// Summary:
// Provides the implementation for operations that get member values. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as getting a value for a property.
//
// Parameters:
// binder:
// Provides information about the object that called the dynamic operation. The
// binder.Name property provides the name of the member on which the dynamic operation
// is performed. For example, for the Console.WriteLine(sampleObject.SampleProperty)
// statement, where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies
// whether the member name is case-sensitive.
//
// result:
// The result of the get operation. For example, if the method is called for a property,
// you can assign the property value to result.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a run-time exception is thrown.)
public virtual bool TryGetMember(GetMemberBinder binder, out object result);
//
// Summary:
// Provides the implementation for operations that invoke an object. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as invoking an object or a delegate.
//
// Parameters:
// binder:
// Provides information about the invoke operation.
//
// args:
// The arguments that are passed to the object during the invoke operation. For
// example, for the sampleObject(100) operation, where sampleObject is derived from
// the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the object invocation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.
public virtual bool TryInvoke(InvokeBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that invoke a member. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as calling a method.
//
// Parameters:
// binder:
// Provides information about the dynamic operation. The binder.Name property provides
// the name of the member on which the dynamic operation is performed. For example,
// for the statement sampleObject.SampleMethod(100), where sampleObject is an instance
// of the class derived from the System.Dynamic.DynamicObject class, binder.Name
// returns "SampleMethod". The binder.IgnoreCase property specifies whether the
// member name is case-sensitive.
//
// args:
// The arguments that are passed to the object member during the invoke operation.
// For example, for the statement sampleObject.SampleMethod(100), where sampleObject
// is derived from the System.Dynamic.DynamicObject class, args[0] is equal to 100.
//
// result:
// The result of the member invocation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result);
//
// Summary:
// Provides the implementation for operations that set a value by index. Classes
// derived from the System.Dynamic.DynamicObject class can override this method
// to specify dynamic behavior for operations that access objects by a specified
// index.
//
// Parameters:
// binder:
// Provides information about the operation.
//
// indexes:
// The indexes that are used in the operation. For example, for the sampleObject[3]
// = 10 operation in C# (sampleObject(3) = 10 in Visual Basic), where sampleObject
// is derived from the System.Dynamic.DynamicObject class, indexes[0] is equal to
// 3.
//
// value:
// The value to set to the object that has the specified index. For example, for
// the sampleObject[3] = 10 operation in C# (sampleObject(3) = 10 in Visual Basic),
// where sampleObject is derived from the System.Dynamic.DynamicObject class, value
// is equal to 10.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.
public virtual bool TrySetIndex(SetIndexBinder binder, object[] indexes, object value);
//
// Summary:
// Provides the implementation for operations that set member values. Classes derived
// from the System.Dynamic.DynamicObject class can override this method to specify
// dynamic behavior for operations such as setting a value for a property.
//
// Parameters:
// binder:
// Provides information about the object that called the dynamic operation. The
// binder.Name property provides the name of the member to which the value is being
// assigned. For example, for the statement sampleObject.SampleProperty = "Test",
// where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, binder.Name returns "SampleProperty". The binder.IgnoreCase property specifies
// whether the member name is case-sensitive.
//
// value:
// The value to set to the member. For example, for sampleObject.SampleProperty
// = "Test", where sampleObject is an instance of the class derived from the System.Dynamic.DynamicObject
// class, the value is "Test".
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TrySetMember(SetMemberBinder binder, object value);
//
// Summary:
// Provides implementation for unary operations. Classes derived from the System.Dynamic.DynamicObject
// class can override this method to specify dynamic behavior for operations such
// as negation, increment, or decrement.
//
// Parameters:
// binder:
// Provides information about the unary operation. The binder.Operation property
// returns an System.Linq.Expressions.ExpressionType object. For example, for the
// negativeNumber = -number statement, where number is derived from the DynamicObject
// class, binder.Operation returns "Negate".
//
// result:
// The result of the unary operation.
//
// Returns:
// true if the operation is successful; otherwise, false. If this method returns
// false, the run-time binder of the language determines the behavior. (In most
// cases, a language-specific run-time exception is thrown.)
public virtual bool TryUnaryOperation(UnaryOperationBinder binder, out object result);
}`enter code here`
}