重载方法以支持引用类型和可为空类型

发布于 2024-08-06 05:08:19 字数 738 浏览 7 评论 0原文

我有一个想要重载的扩展方法,以便它可以处理引用类型和可为空值类型。然而,当我尝试这样做时,我得到“具有相同签名的成员已被声明”。 C# 不能在我的泛型方法上使用 where 限定符来区分它们吗?完成这项工作的明显方法是给每个方法一个不同的名称,但这对我来说似乎不是一个非常优雅的解决方案。完成这项工作的最佳方法是什么?

示例:

public static T Coalesce<T>(this SqlDataReader reader, string property) where T : class
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? null
               : (T) reader[property];
}

public static T? Coalesce<T>(this SqlDataReader reader, string property) where T : struct
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? null
               : (T?)reader[property];
}

// Usage
var id = reader.Coalesce<System.Guid?>("OptionalID");

I have an extension method that I would like to overload so it can handle both reference types and nullable value types. When I try to do this, however, I get "Member with the same signature is already declared." Can C# not use the where qualifier on my generic methods to distinguish them from each other? The obvious way to make this work is to give each method a distinct name, but this doesn't seem like a very elegant solution to me. What is the best way of making this work?

Example:

public static T Coalesce<T>(this SqlDataReader reader, string property) where T : class
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? null
               : (T) reader[property];
}

public static T? Coalesce<T>(this SqlDataReader reader, string property) where T : struct
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? null
               : (T?)reader[property];
}

// Usage
var id = reader.Coalesce<System.Guid?>("OptionalID");

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

差↓一点笑了 2024-08-13 05:08:19

如果 SqlDataReader.Item[string] 属性类型为 object,则此方法有效。

public static T Coalesce<T>(this SqlDataReader reader, string property)
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? default(T)
               : (T) reader[property];
}

This works if the SqlDataReader.Item[string] property type is object.

public static T Coalesce<T>(this SqlDataReader reader, string property)
{
    return reader.IsDBNull(reader.GetOrdinal(property))
               ? default(T)
               : (T) reader[property];
}
若无相欠,怎会相见 2024-08-13 05:08:19

正如 @280Z28 指出的出,根据您的情况,您可以用一种方法处理这两种情况。但是,如果您确实想要两个具有相同签名但基于传入类型具有不同内部结构的方法,这在 C# 中是不可能的。

来自 MSDN 上的 C++ 模板和 C# 泛型之间的差异

  • C# 不支持显式专业化;也就是说,特定类型的模板的自定义实现。
  • C# 不支持部分特化:类型参数子集的自定义实现。

As @280Z28 pointed out, in your case you can handle both cases with one method. However, if you really wanted two methods with the same signature but different internals based on the passed-in type, that isn't possible in C#.

From Differences Between C++ Templates and C# Generics on MSDN:

  • C# does not support explicit specialization; that is, a custom implementation of a template for a specific type.
  • C# does not support partial specialization: a custom implementation for a subset of the type arguments.
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文