workout ultimate precio entreno cellucor dynamic c#-4.0 duck-typing

dynamic - ultimate - Prueba de tipo pato con C#4 para objetos dinámicos



cellucor c4 precio (5)

Implementación del método HasProperty para cada IDynamicMetaObjectProvider SIN arrojar RuntimeBinderException.

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Dynamic; using Microsoft.CSharp.RuntimeBinder; using System.Linq.Expressions; using System.Runtime.CompilerServices; namespace DynamicCheckPropertyExistence { class Program { static void Main(string[] args) { dynamic testDynamicObject = new ExpandoObject(); testDynamicObject.Name = "Testovaci vlastnost"; Console.WriteLine(HasProperty(testDynamicObject, "Name")); Console.WriteLine(HasProperty(testDynamicObject, "Id")); Console.ReadLine(); } private static bool HasProperty(IDynamicMetaObjectProvider dynamicProvider, string name) { var defaultBinder = Binder.GetMember(CSharpBinderFlags.None, name, typeof(Program), new[] { CSharpArgumentInfo.Create( CSharpArgumentInfoFlags.None, null) }) as GetMemberBinder; var callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(name, false, defaultBinder)); var result = callSite.Target(callSite, dynamicProvider); if (Object.ReferenceEquals(result, NoThrowExpressionVisitor.DUMMY_RESULT)) { return false; } return true; } } class NoThrowGetBinderMember : GetMemberBinder { private GetMemberBinder m_innerBinder; public NoThrowGetBinderMember(string name, bool ignoreCase, GetMemberBinder innerBinder) : base(name, ignoreCase) { m_innerBinder = innerBinder; } public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion) { var retMetaObject = m_innerBinder.Bind(target, new DynamicMetaObject[] {}); var noThrowVisitor = new NoThrowExpressionVisitor(); var resultExpression = noThrowVisitor.Visit(retMetaObject.Expression); var finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions); return finalMetaObject; } } class NoThrowExpressionVisitor : ExpressionVisitor { public static readonly object DUMMY_RESULT = new DummyBindingResult(); public NoThrowExpressionVisitor() { } protected override Expression VisitConditional(ConditionalExpression node) { if (node.IfFalse.NodeType != ExpressionType.Throw) { return base.VisitConditional(node); } Expression<Func<Object>> dummyFalseResult = () => DUMMY_RESULT; var invokeDummyFalseResult = Expression.Invoke(dummyFalseResult, null); return Expression.Condition(node.Test, node.IfTrue, invokeDummyFalseResult); } private class DummyBindingResult {} } }

Quiero tener un ejemplo simple de tipa de pato en C # usando objetos dinámicos. Me parece que un objeto dinámico debe tener métodos HasValue / HasProperty / HasMethod con un solo parámetro de cadena para el nombre del valor, propiedad o método que está buscando antes de intentar ejecutarlo. Estoy tratando de evitar probar / atrapar bloques, y una reflexión más profunda si es posible. Simplemente parece ser una práctica común para el tipado de patos en lenguajes dinámicos (JS, Ruby, Python, etc.) que es probar una propiedad / método antes de intentar usarlo, luego volver a caer en un valor predeterminado, o arrojar una excepción controlada . El siguiente ejemplo es básicamente lo que quiero lograr.

Si los métodos descritos anteriormente no existen, ¿alguien tiene métodos de extensión prefabricados para la dinámica que harán esto?


Ejemplo: en JavaScript puedo probar un método en un objeto con bastante facilidad.

//JavaScript function quack(duck) { if (duck && typeof duck.quack === "function") { return duck.quack(); } return null; //nothing to return, not a duck }


¿Cómo haría lo mismo en C #?

//C# 4 dynamic Quack(dynamic duck) { //how do I test that the duck is not null, //and has a quack method? //if it doesn''t quack, return null }


La ruta más corta sería invocarlo y manejar la excepción si el método no existe. Vengo de Python, donde dicho método es común en el pato-tipado, pero no sé si se usa ampliamente en C # 4 ...

No me he probado porque no tengo VC 2010 en mi máquina

dynamic Quack(dynamic duck) { try { return duck.Quack(); } catch (RuntimeBinderException) { return null; } }


Prueba esto:

using System.Linq; using System.Reflection; //... public dynamic Quack(dynamic duck, int i) { Object obj = duck as Object; if (duck != null) { //check if object has method Quack() MethodInfo method = obj.GetType().GetMethods(). FirstOrDefault(x => x.Name == "Quack"); //if yes if (method != null) { //invoke and return value return method.Invoke((object)duck, null); } } return null; }

O esto (usa solo dinámica):

public static dynamic Quack(dynamic duck) { try { //invoke and return value return duck.Quack(); } //thrown if method call failed catch (RuntimeBinderException) { return null; } }


Si tiene control sobre todos los tipos de objetos que usará dinámicamente, otra opción sería forzarlos a heredar de una subclase de la clase DynamicObject que está diseñada para no fallar cuando se invoca un método que no existe:

Una versión rápida y sucia se vería así:

public class DynamicAnimal : DynamicObject { public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result) { bool success = base.TryInvokeMember(binder, args, out result); // If the method didn''t exist, ensure the result is null if (!success) result = null; // Always return true to avoid Exceptions being raised return true; } }

A continuación, puede hacer lo siguiente:

public class Duck : DynamicAnimal { public string Quack() { return "QUACK!"; } } public class Cow : DynamicAnimal { public string Moo() { return "Mooooo!"; } } class Program { static void Main(string[] args) { var duck = new Duck(); var cow = new Cow(); Console.WriteLine("Can a duck quack?"); Console.WriteLine(DoQuack(duck)); Console.WriteLine("Can a cow quack?"); Console.WriteLine(DoQuack(cow)); Console.ReadKey(); } public static string DoQuack(dynamic animal) { string result = animal.Quack(); return result ?? "... silence ..."; } }

Y su salida sería:

Can a duck quack? QUACK! Can a cow quack? ... silence ...

Editar: Debo señalar que esta es la punta del iceberg si puedes usar este enfoque y construir sobre DynamicObject . Puede escribir métodos como bool HasMember(string memberName) si así lo desea.


http://code.google.com/p/impromptu-interface/ Parece ser un buen asignador de interfaz para objetos dinámicos ... Es un poco más trabajo de lo que esperaba, pero parece ser la implementación más limpia de los ejemplos presentado ... Manteniendo la respuesta de Simon como correcta, ya que todavía está más cerca de lo que quería, pero los métodos de la interfaz Impromptu son realmente agradables.