我正在寻找一种动态添加成员动态对象的方法.好的,我想需要一点澄清......
当你这样做:
dynamic foo = new ExpandoObject();
foo.Bar = 42;
Run Code Online (Sandbox Code Playgroud)
该Bar属性将在运行时动态添加.但代码仍然"静态"引用Bar(名称"Bar"是硬编码的)...如果我想在运行时添加属性而不知道它在编译时的名称怎么办?
我知道如何使用类的方法使用自定义动态对象(我实际上是几个月前的博客)DynamicObject,但是如何使用任何动态对象?
我可以使用IDynamicMetaObjectProvider界面,但我不明白如何使用它.例如,我应该将哪个参数传递给GetMetaObject方法?(它期待一个Expression)
顺便说一句,你如何对动态对象进行反射?"定期"反思TypeDescriptor并不显示动态成员......
任何见解将不胜感激!
我需要一些DLR帮助.我正在实现一个IDynamicMetaObjectProvider和DynamicMetaObject,但我遇到了一些问题,获得了预期的返回类型.我在metaobject中覆盖了BindInvokeMember,我可以看到所有的args类型但没有返回类型.有人知道如果可能的话我会怎么做?我知道返回类型是动态的,但是如果你调用的东西依赖于返回类型.除非我知道消费者期望的返回类型,否则我不知道要在DynamicMetaObject中执行哪个操作.
我不能在这里粘贴我的实际代码,因为它调用各种工作的东西.下面是一些示例动态对象代码.
public class TestDynamicMetaObject : DynamicMetaObject
{
public TestDynamicMetaObject(Expression expression, object value)
: base (expression, BindingRestrictions.Empty, value)
{
}
public override DynamicMetaObject BindInvokeMember(InvokeMemberBinder binder, DynamicMetaObject[] args)
{
Delegate method = new Func<int>(Test);
return new DynamicMetaObject(
Expression.Call(method.Method),
BindingRestrictions.GetInstanceRestriction(Expression,Value),
Value
);
}
public static int Test()
{
return 10;
}
}
public class TestDynamicObject : IDynamicMetaObjectProvider
{
DynamicMetaObject IDynamicMetaObjectProvider.GetMetaObject(Expression parameter)
{
return new TestDynamicMetaObject(parameter, this);
}
}
Run Code Online (Sandbox Code Playgroud)
这是我正在使用的地方.
static void Main(string[] args)
{
try
{
dynamic x = new TestDynamicObject(); …Run Code Online (Sandbox Code Playgroud) 我想每个人都已经听说过一些关键开发人员离开Dynamic Languages团队的消息,因为他们认为微软对Dynamic Languages的支持逐渐减弱.
我非常喜欢Python,并经常尝试使用它.所以,通过扩展,我关心IronPython,并希望看到它继续发展.我相信很多人对IronRuby也有同感.但我仍然无法弄清楚的是.NET开发人员为什么要关心IronRuby和IronPython?
如果你写信给微软要求他们继续支持和开发DLR和Iron语言,你会使用什么参数?
如果您说服您的雇主让开发人员有时间为尚未制作的社区支持的IronPython或IronRuby版本做出贡献,那么您将如何在业务价值方面对其进行合理化?
下面是我能想出一些有趣的使用情况,但如果我在那里经理琢磨上面的问题,我可能不会发现它们是令人信服的:
谁能想到更好的东西?
ironpython ironruby dynamic-language-runtime dynamic-languages
我们有一个用于机器自动化的IDE,允许用户通过可视化连接对象和组件来开发解决方案.他们还可以使用C++和C#编写"插件".IDE是使用.NET编写的.它的用户通常不是传统的软件开发和编程,而是更多的是技术/电气和自动化工程师的方向,但他们都需要了解C#和C++编程的基础知识.
如果我们要为IDE本身引入宏/脚本语言,包括交互式控制台(仅限设计时间),我们应该选择哪种语言?它应该是一种动态脚本语言,它在.NET和DLR中具有良好的基础,因为它是未来的证据,并且具有良好的支持和背后的良好动力,但对于我们的特殊开发人员也不会有如此陡峭的学习曲线.理想情况下,如果你了解C++和/或C#,它应该是完全直观的 - 即使你不是一个坚如磐石的软件开发人员.
更新:当前对我们最有吸引力的选项是使用动态编译的C#.我们的用户可以继续使用C#.CSI证明,它甚至可以构建一个交互式控制台.您如何看待这个选项?是否有任何潜在的陷阱/缺点我们(由于我们缺乏一般的脚本编制经验)只是还没有意识到?
我一直在研究使用DLR作为我的玩具语言,我有点困惑.如果.NET 4.0具有LINQ表达式树,动态对象和"动态"类型,那么我们真的需要DLR了吗?DLR提供了什么,这将使我作为语言开发人员的生活更轻松
---编辑----
让我更好地解释一下我的问题.在codeplex(dlr.codeplex.com)上找到的DLR项目是否还有很多需要呢?这个DLR项目的所有功能都归入.NET 4吗?或者在DLR中还有什么价值吗?
Nancy通过dynamic变量将我的查询字符串和表单值传递给我的处理程序.下面的示例显示了通过Nancy请求传递给POST处理程序的表单值,例如Request.Form.xxx.
处理器
Post["/"] = _ =>
{
var userId = (string) Request.Form.userid;
if (userId.IsEmpty()) return HttpStatusCode.UnprocessableEntity;
return HttpStatusCode.OK;
};
Run Code Online (Sandbox Code Playgroud)
您可以看到我正在转换userid为字符串,然后使用字符串扩展方法来检查值是null还是空字符串(相当于string.IsNullOrEmpty()).
我更喜欢的是在动态类型上使用扩展方法,以便在执行任何其他操作之前执行我的健全性检查.我想要这样的代码:
if(Request.Form.userid.IsEmpty()) return HttpStatusCode.UnprocessableEntity;
Run Code Online (Sandbox Code Playgroud)
但是,您不能拥有dynamic类型的扩展方法.此外,您无法通过反射检查是否存在属性.欢迎来到DLR.
题
执行预检查以确保将预期的查询/表单值传递给我的Nancy处理程序的最简单,最安全的方法是什么?
谢谢
在研究C#动态关键字如何工作时,我偶然发现了一些奇怪的行为.它几乎看起来像一个bug,但它可能更有可能是这种行为的原因.
在下面的代码中,有两个调用,一个调用obj1,一个调用obj2,但只有一个调用正确执行.似乎局部变量类型是原因,但也应该可以从IDynamicTarget访问"Hello",因为它扩展了IDynamicTargetBase.
namespace DynamicTesting
{
interface IDynamicTargetBase
{
string Hello(int a);
}
interface IDynamicTarget : IDynamicTargetBase
{
}
class DynamicTarget : IDynamicTarget
{
public string Hello(int a)
{
return "Hello!";
}
}
class Program
{
static void Main(string[] args)
{
dynamic a = 123;
IDynamicTargetBase obj1 = new DynamicTarget();
obj1.Hello(a); // This works just fine
IDynamicTarget obj2 = new DynamicTarget();
obj2.Hello(a); // RuntimeBinderException "No overload for method 'Hello' takes '1' arguments"
}
}
}
Run Code Online (Sandbox Code Playgroud) 要在C#4.0中实现"方法缺失" - 语义等,您必须实现IDynamicObject:
public interface IDynamicObject
{
MetaObject GetMetaObject(Expression parameter);
}
Run Code Online (Sandbox Code Playgroud)
据我所知,IDynamicObject实际上是DLR的一部分,所以它不是新的.但我还没有找到很多关于它的文件.
有一些非常简单的示例实现(这里和这里的 fx ),但是有人能指出更完整的实现或一些真正的文档吗?
特别是,你究竟应该如何处理"参数" - 参数?
在CPython中,我认为,import意味着将py文件编译为pyc文件并在当前帧中执行该文件,下次CPython将直接加载pyc文件而不再编译.如何进口铁腕?我猜ironpython没有类似pyc的格式.每次导入时都会编译吗?
我正在创建表达式树,有一种情况我需要在另一个lambda中创建一个lambda并将一个lambda存储在一个类中并在表达式树中添加该类.这是我想要做的简单示例(此代码无法编译):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Linq.Expressions;
namespace SimpleTest {
public class LambdaWrapper {
private Delegate compiledLambda;
public LambdaWrapper(Delegate compiledLambda) {
this.compiledLambda = compiledLambda;
}
public dynamic Execute() {
return compiledLambda.DynamicInvoke();
}
}
public class ForSO {
public ParameterExpression Param;
public LambdaExpression GetOuterLambda() {
IList<Expression> lambdaBody = new List<Expression>();
Param = Expression.Parameter(typeof(object), "Param");
lambdaBody.Add(Expression.Assign(
Param,
Expression.Constant("Value of 'param' valiable"))
);
lambdaBody.Add(Expression.Call(
null,
typeof(ForSO).GetMethod("Write"),
Param)
);
Delegate compiledInnerLambda = GetInnerLambda().Compile();
LambdaWrapper wrapper = new LambdaWrapper(compiledInnerLambda);
lambdaBody.Add(Expression.Constant(wrapper));
//lambdaBody.Add(GetInnerLambda()); …Run Code Online (Sandbox Code Playgroud)