是否可以动态更改对象的强制转换?

时间:2015-05-01 10:48:26

标签: c# quickfix fix-protocol

我想要一个"指针"到一个对象,但该对象可以是两个类之一。

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动态地以某种方式?

3 个答案:

答案 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
}