请注意,此可能与this question重复,我不完全确定。
我的问题是我有一个类库项目,它引用了第三方类型库(COM)。我想将契约放入类库中的方法中,如下所示:
public class foo
{
public static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
然后有一个客户端项目使用这种方法,例如
var n = foo.divide(null, 4, 2);
但我也希望客户端项目在其某些方法中也使用契约。因此,我将两个项目的“代码约定”属性设置为“执行运行时合同检查”(如果没有这些属性,您将获得运行时声明,告知您需要此设置)。
现在,当我尝试编译客户端时,出现以下错误:
无法解析成员参考:my_class_lib.foo::divide。
ccrewrite:error:由于元数据错误导致重写中止。
这似乎是不可避免的 - 任何时候调用一个类型来自第三方类型库的方法。从方法的签名中删除类型,没关系。
任何人都可以解释为什么会发生这种情况吗?这是一个线索,我的代码结构存在根本缺陷(如果是这样,为什么?),还是代码合同的怪癖? 此问题是否有推荐的解决方法?
答案 0 :(得分:3)
说实话,我不知道为什么 ccrewrite 有互操作类型的问题,但我可以给你3个解决方法:
解决方案1
这是最简单的:
你必须为这两个项目做到这一点。这个解决方案的缺点是在构建之后,您将在bin文件夹中获得一个额外的互操作程序集。
解决方案2
另一种解决方案可能是从公共接口中删除第三方类型库中的类型,即:
public class foo
{
public static int divide(int a, int b)
{
return divide(null, a, b);
}
private static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
当然,只有当您不需要在客户端使用TypeFromTypeLib
时,您才能这样做。
解决方案3
如果您需要在您的客户端使用TypeFromTypeLib
,您可以为此类编写一个包装器,即:
public class MyTypeFromTypeLib
{
//...
}
public class foo
{
public static int divide(MyTypeFromTypeLib mytftl, int a, int b)
{
var tftl = new TypeFromTypeLib();
//Map MyTypeFromTypeLib to TypeFromTypeLib
//...
return divide(tftl , a, b);
}
private static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
但是,这个解决方案很麻烦,因为需要额外的类。