- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
您能给我一些限制 C# 中动态类型的原因吗?我在“Pro C# 2010 和 .NET 4 平台”中读到了它们。这是摘录(如果在这里引用书籍是非法的,请告诉我,我会删除摘录):
While a great many things can be defined using the dynamic keyword, there are some limitations regarding its usage. While they are not show stoppers, do know that a dynamic data item cannot make use of lambda expressions or C# anonymous methods when calling a method. For example, the following code will always result in errors, even if the target method does indeed take a delegate parameter which takes a string value and returns void.
dynamic a = GetDynamicObject();
// Error! Methods on dynamic data can’t use lambdas!
a.Method(arg => Console.WriteLine(arg));To circumvent this restriction, you will need to work with the underlying delegate directly, using the techniques described in Chapter 11 (anonymous methods and lambda expressions, etc). Another limitation is that a dynamic point of data cannot understand any extension methods (see Chapter 12). Unfortunately, this would also include any of the extension methods which come from the LINQ APIs. Therefore, a variable declared with the dynamic keyword has very limited use within LINQ to Objects and other LINQ technologies:
dynamic a = GetDynamicObject();
// Error! Dynamic data can’t find the Select() extension method!
var data = from d in a select d;
提前致谢。
最佳答案
Tomas 的猜想很不错。他对扩展方法的推理是正确的。基本上,为了使扩展方法起作用,我们需要调用站点在运行时以某种方式知道在编译时哪些 using 指令生效。我们根本没有足够的时间或预算来开发一个可以将此信息保存到调用站点的系统。
对于lambdas来说,情况其实比判断lambda是去表达式树还是delegate这个简单的问题要复杂的多。请考虑以下事项:
d.M(123)
其中 d 是动态类型的表达式。 *什么对象应该在运行时作为参数传递给调用站点“M”?很明显,我们通过了 123 框并通过了它。然后,运行时绑定(bind)器中的重载解析算法会查看 d 的运行时类型和 int 123 的编译时类型,并使用它们。
如果是的话会怎样
d.M(x=>x.Foo())
现在我们应该传递什么对象作为参数?我们无法表示“一个变量的 lambda 方法,它调用一个名为 Foo 的未知函数,无论 x 的类型是什么”。
假设我们想要实现这个功能:我们必须实现什么?首先,我们需要一种方法来表示一个未绑定(bind)的 lambda。表达式树的设计目的只是为了表示所有类型和方法都已知的lambda。我们需要发明一种新的“无类型”表达式树。然后我们需要在运行时绑定(bind)器中实现 所有 lambda 绑定(bind)规则。
考虑最后一点。 Lambda 可以包含语句。 实现此功能需要运行时绑定(bind)器包含完整 C# 中每个可能语句的语义分析器。
这超出了我们的预算几个数量级。如果我们想要实现该功能,我们今天仍将致力于 C# 4。
不幸的是,这意味着 LINQ 不能很好地处理动态,因为 LINQ 当然到处都使用无类型的 lambda。希望在 C# 的某些假设的 future 版本中,我们将拥有功能更完备的运行时绑定(bind)程序,并能够对未绑定(bind)的 lambda 进行同象表示。但如果我是你,我不会屏住呼吸等待。
更新:一条评论要求澄清有关语义分析器的问题。
考虑以下重载:
class C {
public void M(Func<IDisposable, int> f) { ... }
public void M(Func<int, int> f) { ... }
...
}
和一个电话
d.M(x=> { using(x) { return 123; } });
假设 d 是编译时类型 dynamic 和运行时类型 C。运行时绑定(bind)器必须做什么?
运行时绑定(bind)程序必须在运行时确定表达式 x=>{...}
是否可转换为 M 的每个重载中的每个委托(delegate)类型.
为此,运行时绑定(bind)器必须能够确定第二个重载不适用。如果适用,那么您可以将 int 作为 using 语句的参数,但 using 语句的参数必须是一次性的。这意味着运行时绑定(bind)器必须知道 using 语句的所有规则,并且能够正确报告 using 语句的任何可能使用是合法还是非法。
显然,这并不局限于 using 语句。运行时绑定(bind)程序必须了解所有 C# 的所有规则,以便确定给定的语句 lambda 是否可转换为给定的委托(delegate)类型。
我们没有时间编写一个运行时绑定(bind)器,它本质上是一个生成 DLR 树而不是 IL 的全新 C# 编译器。通过不允许 lambda,我们只需要编写一个知道如何绑定(bind)方法调用、算术表达式和其他一些简单类型的调用站点的运行时绑定(bind)器。允许使用 lambda 会使运行时绑定(bind)问题的实现、测试和维护成本提高数十倍或数百倍。
关于c# - C# 中动态类型的限制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3588956/
我正在尝试编写一个相当多态的库。我遇到了一种更容易表现出来却很难说出来的情况。它看起来有点像这样: {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE
谁能解释一下这个表达式是如何工作的? type = type || 'any'; 这是否意味着如果类型未定义则使用“任意”? 最佳答案 如果 type 为“falsy”(即 false,或 undef
我有一个界面,在IAnimal.fs中, namespace Kingdom type IAnimal = abstract member Eat : Food -> unit 以及另一个成功
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
在 C# 中,default(Nullable) 之间有区别吗? (或 default(long?) )和 default(long) ? Long只是一个例子,它可以是任何其他struct类型。 最
假设我有一个案例类: case class Foo(num: Int, str: String, bool: Boolean) 现在我还有一个简单的包装器: sealed trait Wrapper[
这个问题在这里已经有了答案: Create C# delegate type with ref parameter at runtime (1 个回答) 关闭 2 年前。 为了即时创建委托(dele
我正在尝试获取图像的 dct。一开始我遇到了错误 The function/feature is not implemented (Odd-size DCT's are not implemented
我正在尝试使用 AFNetworking 的 AFPropertyListRequestOperation,但是当我尝试下载它时,出现错误 预期的内容类型{( “应用程序/x-plist” )}, 得
我在下面收到错误。我知道这段代码的意思,但我不知道界面应该是什么样子: Element implicitly has an 'any' type because index expression is
我尝试将 SignalType 从 ReactiveCocoa 扩展为自定义 ErrorType,代码如下所示 enum MyError: ErrorType { // .. cases }
我无法在任何其他问题中找到答案。假设我有一个抽象父类(super class) Abstract0,它有两个子类 Concrete1 和 Concrete1。我希望能够在 Abstract0 中定义类
我想知道为什么这个索引没有用在 RANGE 类型中,而是用在 INDEX 中: 索引: CREATE INDEX myindex ON orders(order_date); 查询: EXPLAIN
我正在使用 RxJava,现在我尝试通过提供 lambda 来订阅可观察对象: observableProvider.stringForKey(CURRENT_DELETED_ID) .sub
我已经尝试了几乎所有解决问题的方法,其中包括。为 提供类型使用app.use(express.static('public'))还有更多,但我似乎无法为此找到解决方案。 index.js : imp
以下哪个 CSS 选择器更快? input[type="submit"] { /* styles */ } 或 [type="submit"] { /* styles */ } 只是好
我不知道这个设置有什么问题,我在 IDEA 中获得了所有注释(@Controller、@Repository、@Service),它在行号左侧显示 bean,然后转到该 bean。 这是错误: 14-
我听从了建议 registering java function as a callback in C function并且可以使用“简单”类型(例如整数和字符串)进行回调,例如: jstring j
有一些 java 类,加载到 Oracle 数据库(版本 11g)和 pl/sql 函数包装器: create or replace function getDataFromJava( in_uLis
我已经从 David Walsh 的 css 动画回调中获取代码并将其修改为 TypeScript。但是,我收到一个错误,我不知道为什么: interface IBrowserPrefix { [
我是一名优秀的程序员,十分优秀!