C#构造函数重载:新对象。FromOtherObject()?

C#构造函数重载:新对象。FromOtherObject()?,c#,constructor,initialization,overloading,initializer,C#,Constructor,Initialization,Overloading,Initializer,我有两种不同类型的节点,我需要能够以相对简单的方式在它们之间转换。我想在构造函数中这样做,因为这样会使代码更干净 NodeA nodea = new NodeA(); NodeB nodeb = new NodeB.FromNodeA(nodea); 我已经在谷歌上搜索了几个小时,还没有找到一种方法来实现这一点。我想出的最好的解决办法是 public NodeB() { } public static NodeB FromNodeA(NodeA theNodeA) { NodeB

我有两种不同类型的节点,我需要能够以相对简单的方式在它们之间转换。我想在构造函数中这样做,因为这样会使代码更干净

NodeA nodea = new NodeA();

NodeB nodeb = new NodeB.FromNodeA(nodea);
我已经在谷歌上搜索了几个小时,还没有找到一种方法来实现这一点。我想出的最好的解决办法是

public NodeB() { }

public static NodeB FromNodeA(NodeA theNodeA)
{
    NodeB b = new NodeB();
    b.Value = theNodeA.value;
    // etc..
}
但这让代码看起来有点像这样时髦

NodeB b = NodeB.FromNodeA(nodea);
理想情况下,我希望能够做到这一点:

NodeB b = new NodeB().FromNodeA(nodea);
编辑;
或者我已经使用的静态方法是实现这一点的更(传统)正确的方法吗?

您可以使用带有
NodeA
参数的构造函数:

NodeB nodeB = new NodeB(nodeA);
。。。但拥有工厂方法也是一个非常惯用的解决方案。它有各种好处,包括能够有多个名称不同但参数类型相同的方法,例如

TimeSpan.FromSeconds(...)
TimeSpan.FromMinutes(...)
它还允许该方法具有更大的灵活性:

  • 在某些情况下,它可能返回null(例如,对于null输入)
  • 它可以返回对现有对象的引用
  • 它可以返回子类的实例(例如
    Encoding.GetEncoding
  • 您可以将方法组转换为委托,这对于LINQ操作很方便(不需要lambda表达式)
将其设置为构造函数的一个好处是,如果您有一个子类
NodeB
,那么该子类可能有一个构造函数,该构造函数还接受一个
NodeA
,并链接到
NodeB(NodeA)
构造函数。如果没有代码复制,使用工厂方法很难实现同样的目标

根据Alessandro的评论,您可以有一个用户定义的转换运算符,可以是显式的,也可以是隐式的。不过,我会非常小心隐式转换——它们在当时感觉像是一个好主意,但最终会导致后来不清楚的代码

最后,您还可以在
NodeA
上使用
ToNodeB()
方法,或者直接实现,或者作为扩展方法

因此,总结一下,“用户代码”的外观选项如下:

NodeA nodeA = ...;
// One of...
NodeB nodeB = nodeA;                  // Implicit conversion
NodeB nodeB = (NodeB) nodeA;          // Explicit conversion
NodeB nodeB = new NodeB(nodeA);       // Constructor
NodeB nodeB = NodeB.FromNodeA(nodeA); // Factory method
NodeB nodeB = nodeA.ToNodeB();        // Instance or extension method on NodeA

为什么不使用like
(NodeB)a
?我甚至没有考虑过这样做,这会使它更干净,不幸的是,这不一定会产生对象的副本,而且它们在我的实现中确实需要不同。为什么不只重载默认构造函数:
NodeB b=new NodeB(nodea)另一个选项可以使用
ToXXX
模式(可能作为扩展方法),例如
var nodeB=nodeA.ToNodeB()。我想这与静态
FromXXX
@IvanStoev:True有着相同的好处-我可能还是比较完整:)与重载对象构造函数以接受另一个节点作为参数/参数相比,我更喜欢.FromXXX方法的可读性。@MisterNad:是的,我也是。我认为这是一个很好的模式。我接受这个回答,静态的“工厂方法”是正确的方法。感谢您的快速回复。:)