我想要一个"指针"到一个对象,但该对象可以是两个类之一。
QuickFix.Message newOrderSingle;
if (ecn.versionFIX.Equals(VersionFIX.FSS_FIX44))
{
newOrderSingle = new QuickFix.FIX44.NewOrderSingle(
new ClOrdID(masterForm.OrderBook.GetNewClOrdIDBroker(ecn.brokerCode)),
new Symbol(symbol),
new Side(side),
new TransactTime(DateTime.Now),
ordType = new OrdType(OrdType.LIMIT));
}
else
{
newOrderSingle = new QuickFix.FIX42.NewOrderSingle(
new ClOrdID(masterForm.OrderBook.GetNewClOrdIDBroker(ecn.brokerCode)),
new HandlInst('1'),
new Symbol(symbol),
new Side(side),
new TransactTime(DateTime.Now),
ordType = new OrdType(OrdType.LIMIT));
}
然后我想要这样做,其中"设置"是QuickFix.FIX44.NewOrderSingle
的方法:
newOrderSingle.Set(new Price(limitPrice));
相反,我必须这样做:
((QuickFix.FIX44.NewOrderSingle) newOrderSingle).Set(new Price(limitPrice));
这很难读。
我可以改变"演员" NewOrderSingle
动态地以某种方式?
答案 0 :(得分:1)
你有一些选择:
<强>动态强>
您可以使用dynamic
关键字进行&#34; duck typing&#34;:
dynamic order= newOrderSingle;
order.Set(new Price(limitPrice));
不幸的是,当RuntimeBinderException
没有这样的方法(类型为order
f.e。)时,你会松开智能感知并获得FIX42
。
<强> GenericInvoker 强>
您可以使用我的library:
newOrderSingle.DetermineType()
.When((QuickFix.FIX42 msg) => msg.Set(/* ... */))
.Resolve();
不幸的是,你需要硬编码类型。
总结 如果您需要使用这种方法,那么您的课程设计得很糟糕。考虑创建基类/抽象类或某些接口:
interface IMessageSetable
{
Set(Price p);
}
public class FIX44 : IMessageSetable
{
// impl
}
然后:
if (newOrderSingle is IMessageSetable)
((IMessageSetable)newOrderSingle).Set(price);
答案 1 :(得分:0)
如果您有权访问QuickFix.Message
的源代码,则可以添加它。也许你可以将set函数添加到一个通用接口。
真正的脏方式是使用反射。代码看起来像这样:
newOrderSingle.GetType().GetMethod("Set").Invoke(newOrderSingle, new Price(limitPrice)));
(我猜它不会直接编译,需要调整函数参数)
您也可以尝试使用dynamic
数据类型
答案 2 :(得分:0)
只要您使用公共基类QuickFix.Message
,就不能在不进行强制转换的情况下使用特定成员。
如果您有一段代码,您可以在其中使用特定的子类:
if(newOrderSingle is QuickFix.FIX44.NewOrderSingle)
{
QuickFix.FIX44.NewOrderSingle ord44 = (QuickFix.FIX44.NewOrderSingle)newOrderSingle;
// from here on you can work with ord44:
ord44.Set(new Price(limitPrice));
// more code which uses ord44
}