c# - 为什么范围索引对动态不起作用

标签 c# c#-8.0

我有一些代码,它抛出。我不明白为什么。

string s="asdf";
Console.WriteLine(s[1..3]);

dynamic d="asdf";
Console.WriteLine(d[1..3]); // throws 
// RuntimeBinderException: The best overloaded method match for 'string.this[int]' has some invalid arguments

是否有一些静态解析的编译器魔法?生成的 IL 表明了这一点。

callvirt    System.String.Substring

有没有办法在动态声明的表达式上使用范围索引?

最佳答案

Range Indexing 在 C# 8.0 中发布,它不支持动态,它不能被翻译成另一个代码(在本例中是 text.SubString()),这意味着无法在运行时解析.我在 Lambda Tuple 中遇到了与 dynamic 相同的问题还有 C# 8.0。

你可以查看 how this translation work在代码下方的右侧。

public class MyClass {
    public class RangeIndexer
    {
        public string MyString { get; set; }
        public char this[int index] { get => MyString[index]; }
        public string this[Range range] { get => MyString[range]; }
    }

    public void Main() {
        string s = "asdf";
        Console.WriteLine(s[1..3]); // Translate to text.SubString()

        dynamic d = "asdf";
        Console.WriteLine("Index: " + d[1]); // Address to this[int]
        //Console.WriteLine("Range1: " + d[1..3]); // Cannot translate to text.SubString() => Crashed
        Console.WriteLine("Range2: " + d.Substring(1, 2)); // Local method of string
        Console.WriteLine("Range3: " + $"{d}"[1..3]); // Cast as string and translate like Range1

        dynamic rangeIndexer = new RangeIndexer();
        rangeIndexer.MyString = "asdf";
        Console.WriteLine("Range4: " + rangeIndexer[1..3]); // Address to this[range]
    }
}

range indexing 在编译时被 IDE 翻译成 substring() 所以它实际上并没有在 string class 中实现,所以解释了为什么只有单个索引 d[1] 有效,因为它已被声明。

enter image description here

简而言之,我们有两个选择

选项1:事实上,dynamic是使用Reflection技术来解析和抓取是否在变量,方法,..的范围内,这意味着不会再有翻译代码出现在Reflection中。因此,将 dynamic 转换为特定类型将有助于 IDE 基本上转换它们。

选项 2:对象应像 RangeIndexer 类一样实现以作为动态类型工作,以确保反射可以获取它。但几乎经典类型不支持,因此它仅适用于您自己的模型。

关于c# - 为什么范围索引对动态不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61882077/

相关文章:

c# - 如何在linq和EF中做一个简单的搜索功能

c# - 如何使用 Automapper 将原型(prototype)文件重复类型的属性映射到 C# 类的列表属性?

c# - 接口(interface)成员不能有定义

C# 8 switch 表达式,具有相同结果的多个案例

c# - Microsoft.DirectX.AudioVideoPlayback程序不起作用

c# - 如何将与序列化相关的变量变成简洁的单行代码?

c# - LINQ GroupBy 仅在键不为空时选择

c# - 当使用 long 作为参数时,为什么在 long、float 和 decimal 方法之间存在模棱两可的方法调用?

c# - 需要帮助手动添加到字典

c# - 带有客户端证书的 Xamarin Forms https 抛出 WebException