c# - 如何将对象转换为其他接口
问题描述
这是我的代码
该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>
问题来了,我怎样才能将TestDevice
from转换IDevice
为ISubscriberList
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);
}
}
}
//...
}
对不起,如果这是一个转储问题。
解决方案
您可以使用以下方法检查类型和转换对象is
:
if(device is ISubscriber<TestMessage> subscriber){
// Use subscriber
}
但是,您在使用这些类型的模式时应该非常小心,因为它很容易导致方法的行为根据给定对象的类型而有所不同。如果唯一的变化是更好的性能,那可能很好,但这里似乎并非如此。
在这种情况下,最好采用两个单独的参数,一个用于设备,一个用于订阅者。这可能是同一个对象,但该方法不应该关心这一点。您还可以创建一个IDeviceSubscriber
继承自两者的接口。
您还应该小心使用泛型ISubscriber<TestMessage>
是与ISubscriber<TMessage>
. 如果它们是variant ,一个可能可以转换为另一个,但是有一堆使用 co/contra 方差的规则。
在不了解问题域的情况下,很难提供更具体的建议。
推荐阅读
- android - 如何连续执行许多 RxJava2 Flux
- c# - 我想在 C# 控制台中制作蛇游戏,移动问题
- javascript - element.getBoundingClientRect() 的替代方案
- swiftui - 嵌套 ObservableObject 中的 @Published var 仅在第二次更改后才更改。SwiftUI 错误?
- python - 尝试使用 python 发送电子邮件。不知道错误信息是什么意思
- django - 保存前更新模型字段名称
- python - cv2.fastNlMeansDenoising() 的奇怪行为
- ruby-on-rails - 如何通过关联检测has_many的变化?
- pandas - 使用多个数据框创建嵌套数据框
- postgresql - 我应该在此处的 SELECT 子查询中使用 FOR UPDATE DELETE FROM table WHERE id = any(array(SELECT id FROM table WHERE ... LIMIT 100))