为什么 DapperRow.GetType() 返回 null?

2023-12-24

据我所知,Object.GetType() 永远不应该返回 null。 (相关讨论 https://stackoverflow.com/questions/2201007/can-object-gettype-ever-return-null)

Dapper .Query() 返回私有类 DapperRow 实例,将其视为动态对象。我发现了一个奇怪的事情:DapperRow 的 .GetType() 返回 null。

这是重现问题的示例代码。创建一个 C# 项目,引用 Dapper 并打开与 SQL Server(或其他数据库)的连接,使用 .Query() 执行简单的选择查询并检索结果的第一行。使用GetType()获取结果对象的类型,返回值为null。

using (SqlConnection cn = new SqlConnection(csSql))
{
    var rec = cn.Query("select getdate() as D").Single();
    var t = rec.GetType(); // t == null
    Console.WriteLine(t.Name); // null reference exception
}

我怀疑动态或私有类型是导致null的原因,所以我编写了我的类库进行测试:

namespace Lib
{
  public class Blah
  {
    public static dynamic SecretObject;
    static Blah()
    {
        SecretObject = new PrivateType();
    }
  }
  class PrivateType
  {
  }
} 

在另一个项目中,获取动态类型静态字段并调用GetType():

    dynamic obj = Lib.Blah.SecretObject;
    Console.WriteLine(obj.GetType().Name); // "Lib.PrivateType"

根据测试结果,即使将私有类型转换为动态,我仍然可以从GetType()获取私有类型信息,为什么DapperRow.GetType()返回null?


DapperRow在 Dapper 中专门构建和使用,以提供高度优化的行返回,而无需重复标头信息。这是为了帮助压缩对象的大小并减少冗余数据,从而提高效率。

然而,StackExchange 团队似乎比乍一看更进一步地采用了元编程。

DapperRow实施System.Dynamic.IDynamicMetaObjectProvide接口,这要求获取元对象 https://github.com/StackExchange/Dapper/blob/61e965eed900355e0dbd27771d6469248d798293/Dapper/SqlMapper.DapperRow.cs#L80实施方法:

System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(
    System.Linq.Expressions.Expression parameter)
{
    return new DapperRowMetaObject(parameter, 
        System.Dynamic.BindingRestrictions.Empty, this);
}

DapperRowMetaObject is a 自定义实现 https://github.com/StackExchange/Dapper/blob/61e965eed900355e0dbd27771d6469248d798293/Dapper/SqlMapper.DapperRowMetaObject.cs of DynamicMetaObject它本质上劫持并覆盖了可以针对动态类型调用哪些方法以及这些调用应该转换为什么。在这种情况下,调用除 DapperRow 的 IDictionary.Item getter 或DapperRow.SetValue将会失败,因为它们总是被路由到这两个调用,但值将是默认为空 https://github.com/StackExchange/Dapper/blob/61e965eed900355e0dbd27771d6469248d798293/Dapper/SqlMapper.DapperRow.cs#L42对于表中不存在目标属性的任何“get”调用。

public bool TryGetValue(string name, out object value)
{
    var index = table.IndexOfName(name);
    if (index < 0)
    { // doesn't exist
        value = null;
        return false;
    }
    ...
}

此时,对空动态值调用的任何方法都将抛出RuntimeBinderException:

RuntimeBinderException:无法对 null 执行运行时绑定 参考

您可以通过替换来轻松检验这个假设GetType()另一个调用将抛出完全相同的异常:

var rec = cn.Query("select getdate() as D").Single();
var t = rec.AsEnumerable();
Console.WriteLine(t.ToList());

请记住,任何属性的基础类型信息on动态对象本身仍然可以直接访问:

var rec = cn.Query("select getdate() as D").Single();
var t = rec.D.GetType();
Console.WriteLine(t.Name);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么 DapperRow.GetType() 返回 null? 的相关文章

  • 以编程方式获取命名管道的系统名称

    我正在使用 WCF NetNamedPipeBinding 编写进程间通信 我的目标是让服务在 net pipe localhost service 上运行 所以我运行最简单的主机 host new ServiceHost contract
  • 输出 objdump -t 的输出中的“.hidden”是什么意思?

    Example objdump Logger cpp o t 00000000 g F text 00000000 hidden sti 10 Logger cpp 0b2ae32b 这意味着符号的可见性被隐藏 https develope
  • 如何将 int.TryParse 与可为空的 int 一起使用? [复制]

    这个问题在这里已经有答案了 我正在尝试使用 TryParse 来查找字符串值是否为整数 如果该值为整数 则跳过 foreach 循环 这是我的代码 string strValue 42 if int TryParse trim strVal
  • 如何使用c#/VB.NET在word中插入书签

    我正在尝试使用 C 在 Word 文档中添加书签 但它不起作用 而且我在 msdn 文档和互联网上都找不到任何帮助 这就是我正在尝试做的事情 我正在阅读 Word 文档 然后在该文档中搜索关键字 然后将该文本转换为超链接 效果很好 现在 我
  • pybind11 返回 numpy 对象数组

    使用 pybind11 C API 和 python3 我们如何在 C 实现中正确创建一个 numpy 对象数组 即 unicode 字符串 并将其返回给 python 传递到 pybind11 array 的底层数据数组的确切内存布局是什
  • 清理 STL 指针列表/向量

    您可以想出的最短的 C 块是多少来安全地清理std vector or std list指针 假设您必须对指针调用删除 list
  • Web API 2 中的方法名称约定 [关闭]

    Closed 这个问题需要多问focused help closed questions 目前不接受答案 是否有 Web API 2 中使用的约定的列表 以这两种方法为例 两者都可以工作 但都没有用属性来装饰 IHttpActionResu
  • QFileDialog::getOpenFileName 调试时崩溃,显然是由项目名称引起的?

    我遇到了一个让我非常困惑的问题 我在 Windows 7 上使用 Qt Creator 3 1 2 和 Qt 5 3 使用 MSVC 10 0 编译器和 Windows 8 1 调试工具中的 CDB 不确定我是否应该寻找特定于 Window
  • 使用 C# 从文本中删除数字

    我有一个要处理的文本文件 其中有一些数字 我只想要其中的文字 而不是其他任何东西 我成功删除了标点符号 但是如何删除数字呢 我想要使 用 C 代码 另外 我想删除长度大于 10 的单词 如何使用 Reg 表达式来做到这一点 您可以使用正则表
  • 将 boost::iostreams::mapped_file_source 与 std::multimap 一起使用

    我有相当大量的数据需要分析 每个文件大约有 5gig 每个文件的格式如下 xxxxx yyyyy 键和值都可以重复 但键是按升序排列的 我正在尝试使用内存映射文件来实现此目的 然后找到所需的键并使用它们 这是我写的 if data file
  • 在.NET MVC中,有没有一种简单的方法来检查我是否在主页上?

    如果用户从主页登录 我需要采取特定的操作 在我的 LogOnModel 中 我有一个隐藏字段 Html Hidden returnUrl Request Url AbsoluteUri 在我的控制器中 我需要检查该值是否是主页 在下面的示例
  • 确定所选电子邮件是来自收件箱还是已发送邮件

    我正在编程Outlook 插件并需要确定所选电子邮件是否来自Inbox or Sent Items这样当我将电子邮件保存到数据库中时 我可以使用文件夹 收件箱 或 已发送 来标记电子邮件 我知道我可以将文件夹名称与 收件箱 或 已发送邮件
  • 将图像添加到 ASP.Net 中的单选按钮列表

    我正在尝试将图像添加到单选按钮列表控件 但它不起作用 我试过这个 RadioButtonList2 Items Add new ListItem String Format src Colors Dallas 625527 1 1 png
  • 以编程方式打开网页并以字符串形式检索其 html 包含内容

    我有一个 Facebook 帐户 我想提取我朋友的照片及其个人详细信息 例如 出生日期 就读学校 等 我能够提取我每个朋友帐户的 Facebook 首页的地址 但我不知道如何以编程方式打开我每个朋友首页的网页并将 html 包含保存为字符串
  • 无法在 Visual Studio Code 的 C# 输出上键入任何内容

    所以我试图在 vscode 上运行一个非常基本的 C 程序 代码如下 using System namespace HelloWorld class Program static void Main string args string N
  • Web Api 2 在 OWIN 中间件中获取控制器和操作名称?

    如何在自定义 OWIN 中间件中检索 api 控制器名称和 api 操作名称 我可以在消息处理程序内部执行此操作 如下所示 var config request GetConfiguration var routeData config R
  • 使用循环在 C 中管道传输两个或多个 shell 命令

    我正在尝试执行ls wc l通过 C 语言程序 而不是使用命令行 这是我当前的工作代码 int main int pfds 2 pipe pfds pid t pid fork if pid 0 The child process clos
  • 为什么在 C++ 内存管理中术语“自动”和“动态”优于术语“堆栈”和“堆”?

    与 SO 上的许多问题和答案相关 我了解到最好将其生命周期管理为驻留在自动存储中而不是堆栈中的对象 此外 动态分配的对象不应该被称为驻留在堆上 而应该被称为驻留在动态存储中 我知道有自动 动态和静态存储 但从未真正理解自动堆栈和动态堆之间的
  • 同时使用多个控制台

    是否有捷径可寻 我现在仅使用控制台测试我的网络应用程序 最好的办法是从一个项目中拥有多个控制台 然后按一下 立即调试 菜单项 我可以像过去一样使用多个项目 但这似乎很笨拙 理想情况下 我可以启动多个控制台实例 从同一线程运行很好 并且让它们
  • printf 右对齐括号内的数字

    我正在编写一个程序 显示数组中的所有信息 它必须以括号中的数组索引开头 例如 2 并且它们必须彼此正确对齐 如果只是数字 我知道你可以这样做 printf 10d index 但是用括号括起来会得到以下输出 1 2 10 11 当我真正希望

随机推荐

  • 我的解决方案中有两个 Web 项目,要部署哪一个

    我有一个像这样结构的解决方案 Proj Soln Proj Api csproj Proj Web csproj 我已使用 bitbucket org 配置了 microsoft azure 当我通过 git 提交到 bitbucket 时
  • Linux Mint 19.2 上的 Docker 安装不起作用 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 刚刚安装了一个新的 Linux mint 19 2 我需要 docker 所以我去了 docker 文档并遵循了该过程 https doc
  • 将值传递给捆绑的 React JS 文件?

    我想知道是否可以将参数传递给反应入口点 我的入口点如下所示 module exports entry js components Application js output path dist filename bundle js 我的应用
  • 如何在turbo c++ 16位编译器中创建项目

    我想创建一个项目文件 Turbo C 并链接该项目中的文件 虽然我已经尝试过 但我发现只有一个选项可以打开项目 没有选项可以创建新项目 那么如何做到这一点 基本上 你想做的是 开放项目 在那里 您输入项目名称 它必须以 PRJ 当你open
  • Angular2 中的事件委托

    我正在 ng2 中开发一个应用程序 但我正在努力解决一些问题 我正在构建一个日历 您可以在其中选择日期范围 我需要对此做出反应click mouseenter mouseleave日细胞上的事件 所以我有一个像这样的代码 简化的 日历 组件
  • 如何更改 SonataAdmin 中的“奏鸣曲项目”链接?

    我的 SonataAdminBundle 有问题 我找不到如何更改左侧板上的 奏鸣曲项目 链接 我有 我的标题 一张图片 下面有 奏鸣曲项目 我怎样才能改变这个 In order to customize the content of th
  • crypto.pbkdf2 导出 IV 和密钥到 crypto.createCipheriv 的正确设置是什么?

    在 Node js 的应用程序中 我使用加密模块 https nodejs org api crypto html用于对称加密 解密 我正在使用 AES 256 CTR 我最初假设加密 createCipher https nodejs o
  • 应用程序 onCreate 在 Activity onCreate 之后调用(未调用)

    在崩溃日志中 我发现了非常奇怪的应用程序错误 该错误发生在 Android 7 0 8 0 上 对于一些少量用户来说 但非常频繁 我无法重现该问题 这里的代码反映了当前应用程序的状态 我有一个对我的应用程序类的静态引用 public cla
  • 防止delayed_job后台作业在单个服务器上消耗过多的CPU

    我的 Rails 应用程序有许多任务被卸载到后台进程中 例如调整图像大小和上传到 S3 我在用着延迟作业 http github com collectiveidea delayed job tree master来管理这些流程 这些过程
  • Java:观察目录以移动大文件

    我一直在编写一个程序来监视目录 当在其中创建文件时 它会更改名称并将它们移动到新目录 在我的第一个实现中 我使用了 Java 的 Watch Service API 当我测试 1kb 文件时 它运行良好 出现的问题是 实际上创建的文件大小在
  • 如何在新行而不是主行中呈现 CKEditor5 工具栏按钮?

    我从源代码将 CKEditor5 集成到我的 create React 应用程序中 现在 我想在工具栏的新行中渲染溢出的按钮 但它们显示在单独的菜单项中 如何在新行而不是主行中显示按钮 这是我的配置 ClassicEditor defaul
  • 无法在 git 中复制和粘贴 - macos

    有谁知道如何使用 macOS 复制并粘贴 git 吗 我无法在左下窗格中选择 突出显示和复制其中的文本 更改 Thanks 我可以通过按以下命令从 gitk 复制 fn C
  • 如何从 TreeNode.FullPath 数据获取实际的树节点?

    我想存储 TreeNode FullPath 中的一些数据 然后我想重新扩展到目前为止的所有内容 有简单的方法吗 多谢 您可以将其编写为扩展方法TreeNodeCollection using System using System Lin
  • 仅显示 ISO 8601 时间戳的 12 小时时间格式

    所以我想在我的 iOS 应用程序的标签中显示从服务器传递的时间 但我在尝试找出如何设置正确的 NSDateFormatter 时遇到了麻烦 例如 我以这种格式从服务器获取此时间戳 2013 02 27T18 15 00 0800 我基本上想
  • 如何获得英文版的Win32Exception?

    我正在努力得到所有Exception消息都是英文的 无论我的程序运行在什么语言上 我已经使用以下帖子中的答案设法获得了几乎所有英文异常消息 异常消息是英文的吗 https stackoverflow com questions 209133
  • Flexbox 容器中的省略号[重复]

    这个问题在这里已经有答案了 自从最新 版本的 Firefox Nightly 35 0a1 以来 我一直遇到一个问题text overflow ellipsis在 Flexbox 容器内flex direction row 每列宽 50 D
  • WebGL GLSL 片段着色器在 iOS 上不起作用

    我正在使用经典柏林噪声 vec3 函数here https gist github com patriciogonzalezvivo 670c22f3966e662d2f83 classic perlin noise 当我在 MacBook
  • Windows 8 低功耗蓝牙 API 示例

    有没有人找到关于如何使用 C C 在 Windows 8 上发现 连接和断开 BLE 设备的好示例 我不确定如何获取与 蓝牙低能耗功能 API 一起使用的设备句柄http msdn microsoft com en us library w
  • 如何在codeigniter中显示电子邮件中的图像?

    this gt load gt library upload this gt load gt library email this gt email gt set newline r n this gt email gt from emai
  • 为什么 DapperRow.GetType() 返回 null?

    据我所知 Object GetType 永远不应该返回 null 相关讨论 https stackoverflow com questions 2201007 can object gettype ever return null Dapp