首页 > 解决方案 > 如何将对象转换为其他接口

问题描述

这是我的代码

IDevice接口用于声明该类是MessageBus.

public interface IDevice
{
    int ID{ get;}
}

ISubscriber<>用于声明该类是订阅者并已订阅TMessage

public interface ISubscriber<TMessage> where TMessage : IMessage
{
    void Listen(TMessage message);
}

IMessage用于声明消息。

public interface IMessage { }

这里定义了一条消息和一个订阅该消息的设备

public class TestMessage : IMessage { }

public class TestDevice : IDevice, ISubscriber<TestMessage>

问题来了,我怎样才能将TestDevicefrom转换IDeviceISubscriberList

public class MessageBus
{
    //key: Type of message
    public Dictionary<Type, List<ISubscriber<IMessage>>> SubscriberList { get; }

    //...

    public void Subscribe(IDevice device)
    {
        var deviceInfo = device.GetType();
        var isSubscriber = deviceInfo.GetInterfaces().Any(item => item.IsGenericType && 
        if (isSubscriber)
        {
            var subscriptionList = deviceInfo.GetInterfaces().Cast<Type>().ToList().FindAll(item => item.IsGenericType && item.GetGenericTypeDefinition() == typeof(ISubscriber<>));
            foreach (var subscription in subscriptionList)
            {
                var message = subscription.GenericTypeArguments.First();
                if (!SubscriberList.ContainsKey(message))
                {
                    SubscriberList.Add(message, new List<ISubscriber<IMessage>>());
                }
                //Here is the problem come from, how to cast the device from IDevice into ISubscriber<TestMessage> or ISubScriber<message>
                SubscriberList[message].Add(device);

            }

        }
    }

    //...
}

对不起,如果这是一个转储问题。

标签: c#.netinterfacecasting

解决方案


您可以使用以下方法检查类型和转换对象is

if(device is ISubscriber<TestMessage> subscriber){
     // Use subscriber
}

但是,您在使用这些类型的模式时应该非常小心,因为它很容易导致方法的行为根据给定对象的类型而有所不同。如果唯一的变化是更好的性能,那可能很好,但这里似乎并非如此。

在这种情况下,最好采用两个单独的参数,一个用于设备,一个用于订阅者。这可能是同一个对象,但该方法不应该关心这一点。您还可以创建一个IDeviceSubscriber继承自两者的接口。

您还应该小心使用泛型ISubscriber<TestMessage>是与ISubscriber<TMessage>. 如果它们是variant ,一个可能可以转换为另一个,但是有一堆使用 co/contra 方差的规则。

在不了解问题域的情况下,很难提供更具体的建议。


推荐阅读