c# - C#泛型方法选择
问题描述
我正在尝试用 C# 编写可以处理不同维度几何实体的通用算法。
在下面的人为示例中,我有Point2
和Point3
,它们都实现了一个简单的IPoint
接口。
现在我有一个GenericAlgorithm
调用函数的函数GetDim
。该函数根据类型有多种定义。还有一个为任何实现IPoint
.
我最初预计以下程序的输出是 2、3。但是,它是 0、0。
interface IPoint {
public int NumDims { get; }
}
public struct Point2 : IPoint {
public int NumDims => 2;
}
public struct Point3 : IPoint {
public int NumDims => 3;
}
class Program
{
static int GetDim<T>(T point) where T: IPoint => 0;
static int GetDim(Point2 point) => point.NumDims;
static int GetDim(Point3 point) => point.NumDims;
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim(point);
static void Main(string[] args)
{
Point2 p2;
Point3 p3;
int d1 = GenericAlgorithm(p2);
int d2 = GenericAlgorithm(p3);
Console.WriteLine("{0:d}", d1); // returns 0 !!
Console.WriteLine("{0:d}", d2); // returns 0 !!
}
}
好的,所以由于某种原因,具体类型信息丢失在GenericAlgorithm
. 我不完全理解为什么会发生这种情况,但是很好。如果我不能这样做,我还有什么其他选择?
解决方案
这种方法:
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim(point);
……总会打电话GetDim<T>(T point)
的。重载决议是在编译时执行的,在那个阶段没有其他适用的方法。
如果你想在执行时调用重载决议,你需要使用动态类型,例如
static int GenericAlgorithm<T>(T point) where T : IPoint => GetDim((dynamic) point);
但是为此使用继承通常是一个更好的主意-在您的示例中,显然您可以只使用单个方法和 return point.NumDims
。我假设在您的真实代码中,有一些原因等效于做起来比较棘手,但是如果没有更多上下文,我们无法建议如何使用继承来执行专业化。这些是您的选择:
- 基于目标的执行时类型的专门化的继承(首选)
- 执行时重载解决方案的动态类型
推荐阅读
- php - 正则表达式匹配部分行,然后看后面并替换(并删除该行)
- ios - 如何使用 Swift SpriteKit 在 For 循环中一一创建 SKSprite 节点
- ruby - 作为 TTY 输出到 $stdout 并同时捕获输出
- python-2.7 - Tkinter 列表框中的行为差异,箭头键与鼠标单击
- angular - 服务中的 Angular2 变量未更新
- html - 嵌套 div 时不要在宽度中包含边距/填充
- pdf - 如何检测或隐藏对 .pdf 文档的修改?
- r - 如何将文本文件中的数据转换为数据框?
- sql - Amazon S3 Select From 不工作
- jquery - jquery ui对话框中的基础日期选择器在Internet Explorer中不起作用