请注意,这可能与此问题重复,我不完全确定.
我的问题是我有一个类库项目,它引用了第三方类型库(COM).我想将契约放入类库中的方法,如下所示:
public class foo
{
public static int divide(TypeFromTypeLib tftl, int a, int b)
{
Contract.Requires<ArgumentException>(b != 0);
return a / b;
}
}
Run Code Online (Sandbox Code Playgroud)
然后让客户项目使用这种方法,例如
var n = foo.divide(null, 4, 2);
Run Code Online (Sandbox Code Playgroud)
但我也希望客户端项目在其某些方法中也使用契约.因此,我将两个项目的Code Contracts属性设置为'执行运行时合同检查'(没有它,您将获得运行时断言,告诉您它需要此设置).
现在,当我尝试编译客户端时,我收到以下错误:
无法解析成员引用:my_class_lib.foo::divide.
ccrewrite:error:由于元数据错误而重写中止.
这似乎是不可避免的 - 任何时候调用一个类型来自第三方类型库的方法.从方法的签名中删除类型,没关系.
谁能解释为什么会这样?这是一个线索,我的代码结构从根本上是有缺陷的(如果是,为什么?),或者它是代码合同的怪癖?是否有针对此问题的建议修复程序?
最近发现了依赖注入,我现在正试图掌握使用它的频率和距离。
例如,假设我有一个对话框,提示用户输入他们的注册详细信息——名字、姓氏、电话号码、序列号——诸如此类。应以各种方式验证数据(例如,名字和姓氏不为空,序列号为特定长度)。一旦通过验证,它应该被缓存在本地机器上,并发送到注册服务器。只有在所有这些事情都成功或用户取消后,该对话框才应关闭。
所以这可能是我们在这里尝试实现的四件事(职责):UI、验证、本地缓存、将数据发送到非本地服务器。
对话的职责是什么,应该注入什么?显然对话框是 UI,但是验证、缓存和数据发送都应该被注入吗?我认为他们这样做,否则对话框类必须知道数据字段背后的逻辑才能进行验证,它必须知道如何以及在何处缓存数据,以及如何将数据发送到某个地方。如果是这样,这可能会导致调用者端出现一些繁重的代码(假设我们通过构造函数进行注入,我认为这比 setter 函数更可取),例如
MyDialog dlg(new validator(), new cacher(), new sender());
Run Code Online (Sandbox Code Playgroud)
但也许这没问题?在多年看到诸如对话框之类的东西做所有事情的代码之后,它现在对我来说确实有点陌生。但我也可以看到这种情况如何迅速升级——如果还有其他各种各样的小事情需要做——有多少被注入的东西变得“太多”了?
请不要试图在示例场景中挑漏洞,我只是用它来说明。我对 DI 的原则更感兴趣,以及在什么时候你可能会走得太远。
我想知道这段代码是否表现出正确的C++行为?
class Foo
{
public:
Foo(std::string name) : m_name(name) {}
Foo(const Foo& other) {
std::cout << "in copy constructor:" << other.GetName() << std::endl;
m_name = other.GetName();
}
std::string GetName() const { return m_name; }
void SetName(std::string name) { m_name = name; }
private:
std::string m_name;
};
Foo CreateFoo(std::string name)
{
Foo result(name);
return result;
}
void ChangeName(Foo& foo)
{
foo.SetName("foofoo");
}
int _tmain(int argc, _TCHAR* argv[])
{
Foo fooA("alan");
std::cout << "fooA name: " << fooA.GetName() << std::endl;
bool b …Run Code Online (Sandbox Code Playgroud)