【发布时间】:2009-08-20 17:23:44
【问题描述】:
我有一个第三方闭源应用程序,它导出一个 COM 接口,我通过 Interop 在我的 C#.NET 应用程序中使用该接口。这个 COM 接口导出许多对象,这些对象都显示为 System.Object,直到我将它们转换为适当的接口类型。我想分配所有这些对象的属性。因此:
foreach (object x in BigComInterface.Chickens)
{
(x as Chicken).attribute = value;
}
foreach (object x in BigComInterface.Ducks)
{
(x as Duck).attribute = value;
}
但是分配属性很可能(出于不可避免的特定于应用程序的原因)抛出我想从中恢复的异常,所以我真的想要对每个异常进行尝试/捕获。因此:
foreach (object x in BigComInterface.Chickens)
{
try
{
(x as Chicken).attribute = value;
}
catch (Exception ex)
{
// handle...
}
}
foreach (object x in BigComInterface.Ducks)
{
try
{
(x as Duck).attribute = value;
}
catch (Exception ex)
{
// handle...
}
}
显然,这样做会干净得多:
foreach (object x in BigComInterface.Chickens)
{
SetAttribute<Chicken>(x as Chicken, value);
}
foreach (object x in BigComInterface.Ducks)
{
SetAttribute<Duck>(x as Duck, value);
}
void SetAttribute<T>(T x, System.Object value)
{
try
{
x.attribute = value;
}
catch
{
// handle...
}
}
看到问题了吗?我的 x 值可以是任何类型,因此编译器无法解析 .attribute。 Chicken 和 Duck 不在任何类型的继承树中,它们不共享具有 .attribute 的接口。如果他们这样做了,我可以在 T 上对该接口进行约束。但由于该课程是闭源的,这对我来说是不可能的。
在我的幻想中,我想要的是类似于一个约束,要求参数具有 .attribute 属性,无论它是否实现给定的接口。也就是说,
void SetAttribute<T>(T x, System.Object value) where T:hasproperty(attribute)
除了为鸡、鸭、牛、羊等每个人剪切/粘贴这个小尝试/捕获块之外,我不知道从这里做什么。
我的问题是:当在编译时无法知道实现该属性的接口时,想要调用对象上的特定属性的问题有什么好的解决方法?
【问题讨论】:
标签: c# generics properties interface