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:是的,我也是。我认为这是一个很好的模式。我接受这个回答,静态的“工厂方法”是正确的方法。感谢您的快速回复。:)