1

我使用以下语法创建了一个对象:

var newMessage = Activator.CreateInstance(client.Key);

它似乎创建了一个正确类型的对象并允许设置对象属性。但是,当我将对象传递给带有签名的方法时:

public void Publish<T>(T messageBody)

T 定义的 Type 是 object。

我该如何解决这个问题?我无法更改方法签名 - 它来自库 - 我需要能够在运行时创建对象而不事先知道它们的类型。

更新

我尝试执行的功能与发送(发布)消息有关。通常我会注册一个消息处理程序,例如:

RegisterHandler<MyMessage> (m => do something with message );

然后可以打电话

Publish<MyMessage> (message)

最终将在处理程序处结束。这很酷并且工作正常。

我想要做的是插入一个中介作为交换并将消息发布到多个处理程序。我知道我可以使用其他东西来为我做这件事,例如 RabbitMQ,但我希望能够通过对当前代码进行小的修改来实现它。

所以我有一个注册订阅的方法:

 public virtual void registerSubscription<T1,T2>()
    {
        if (handlerMap.ContainsKey(typeof(T2)))
        {
            throw new ArgumentException("Message handler has already been registered for type: " +typeof(T2).Name);
        }
        if (!handlerMap.ContainsValue(typeof(T1)))
        {                              
            mqHost.RegisterHandler<T1> (m => distributeMessage(m) );
        }
        handlerMap[typeof(T2)] = typeof(T1);
    }

我用两个类调用该方法,一个基类和一个继承基类的类:

public class MyMessage
{
    public string name {get;set;}
}

public class MyMessage2:MyMessage{}

这一点效果很好,我得到了一张处理程序的地图。当我做下一点,distributeMessage 方法时,问题就来了。

var match = handlerMap.Where(i => i.Value == message.Body.GetType());
foreach (var client in match)
{
    var newMessage = Activator.CreateInstance(client.Key);
    newMessage.PopulateWith(message.Body);                
    messageProducer.Publish(createMessage(newMessage));                
}

messageProducer.publish 具有签名:

public void Publish<T>(T messageBody)

我不能(轻松)修改它 - 它是图书馆的一部分。我可以调用另一种方法:

public void Publish<T>(IMessage<T> message)

但我看不出这会更容易,因为我必须创建一个仍然需要 .

4

4 回答 4

4

给定调用 Activator 时知道的类型信息,您可以使用一些反射来尝试创建 Publish 的通用方法。如果我误解了您要执行的操作,请询问,我可以修改此代码。

object newObject = Activator.CreateInstance(myType);

var publishMethod = typeof(MessageProducer).GetMethod("Publish");
var publishMethodWithCorrectType = publishMethod.MakeGenericMethod(new Type[] { myType });

publishMethodWithCorrectType.Invoke(messageProducer, new object[]{newObject});

我希望这有帮助。

于 2013-03-31T20:00:47.363 回答
1

尝试这样做:

var newMessage = (MyType)Activator.CreateInstance(client.Key);

ps MyType 是基本类型或接口...

于 2013-03-31T19:06:23.553 回答
0

您还需要Publish<T>通过反射调用该方法才能继续沿着这条路线前进。

另一个建议是class根据类型使对象的类通用client.Key,然后在该类中实现 Publish 方法 - 实现将知道是什么T

于 2013-03-31T19:15:54.660 回答
0

找到另一个问题的答案

并实现了这个:

 typeof(MessageExchange)
   .GetMethod("createMessage",BindingFlags.Static | BindingFlags.NonPublic)
   .MakeGenericMethod(newMessage.GetType())
   .Invoke(null, new object[] { newMessage });

我现在得到了正确的类型。

于 2013-03-31T20:00:44.973 回答