创建唯一目的是隐式转换为另一个类的类是否不好?


10

想象一下一种情况,我们正在使用一个允许您创建Circle对象的库,您可以在其中指定半径和圆心来定义它。但是,由于某些原因,它也需要一个必需的flavour参数。现在,我们确实需要Circle在自己的应用程序中使用,但是出于我的应用程序的目的,我可以将风味设置为Flavours.Cardboard每次。

为了“解决”这一问题,我Circle在另一个命名空间中创建了自己的类,该命名空间仅将radiuscenter作为参数,但具有一个隐式转换器,可以直接转换为Circle仅创建Circle(this.radius, this.center, Flavours.Cardboard)对象的外部库类。因此,在任何需要其他类型的的地方Circle,我都会进行自动转换。

创建这样一个类的后果是什么?有更好的解决方案吗?如果我的应用程序是在此外部库的基础上构建的供其他程序员使用的API,会有所不同吗?


这似乎是Adapter Pattern的一种变体,尽管在这里似乎具有可疑的价值(这只是避免设置参数的一种便利)。
罗伯特·哈维

5
为什么不创建MakeCircle 函数
user253751 '16

1
@immibis Thay是我的第一个念头。在制作游戏时,我通常会按照makePlayer自己的方式创建一个函数,该函数仅接受坐标以将玩家放置在其上,但委托给一个更为复杂的构造函数。
Carcigenicate's

Answers:


13

虽然并不总是不好,但是隐式转换是您的最佳选择,这种情况很少见。

有问题。

  1. 隐式转换不是很可读。
  2. 因为您要创建一个新对象,所以原始对象的任何更改都不会被您转换到的对象看到,从而导致错误。
  3. 如果您要丢掉该对象,那是多余的垃圾需要清理。
  4. 如果存在问题,它将在转换发生时发生,而不是在创建事物时发生,从而使更难以跟踪的错误。

通常,有更好的解决方案。

  1. 制作自己的内部使用其他类/框架的薄包装器。
  2. 创建一个辅助方法,该方法接受所需的构造函数参数并提供固定的参数,从而返回真实对象,而无需指定您不需要的参数。
  3. 从问题类继承并提供您自己的更好的构造函数。
  4. 意识到传递额外的参数确实没什么大不了的。

我个人认为,#2是最简单的实现,并且对设计的负担最小。鉴于情况以及您要对这些类尝试做什么,其他方法也可以。

隐式转换是不得已的方法,只有当我拥有要创建的C ++样式函子时,对我来说才真正值得-隐式转换为委托类型的策略对象。


1

给定您要描述的场景,您可以从部分功能应用程序的角度来考虑。

构造函数是一个函数(至少在理论上;在C#中,您可以创建一个调用该构造函数的“工厂函数”):

Func<double, Point, Flavour, Circle> MakeCircle = (r, p, f) => new Circle(r, p, f);

对于部分应用,满足以下条件:

public static Func<T1, T2, R> Partial<T1, T2, T3, R>(this Func<T1, T2, T3, R> func, T3 t3)
   => (t1, t2) => func(t1, t2, t3);

现在,您可以获得仅需要2个参数的构造函数:

Func<double, Point, Circle> MakeCardboardCircle = Circle.Partial(Flavours.Cardboard)

因此,现在您有了具有所需参数的工厂功能

Circle c = MakeCardboardCircle(1.0, new Point(0, 0)))

顺便说一句,从功能上来说,这显然等同于上面的选项2。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.