希望有人可以对这一点有所了解。我有一个带可选参数的接口。我们使用Unity。如果我尝试更改方法实现中的可选参数,它可以直接使用,但Unity对象使用接口的默认值 - 而不是已实现的方法的默认值。
设定:
public interface ITestOptional {
string HappyMethod(string input, bool amHappy = false);
}
public class TestingOptional : ITestOptional {
public string HappyMethod(string input, bool amHappy = true) {
if (amHappy) return input + " is Happy!";
return input + " is Not Happy!";
}
}
添加到Unity:
container.RegisterType<ITestOptional, TestingOptional>();
并测试:
//direct call
var testDirect = new TestingOptional();
string happyDirect = testDirect.HappyMethod("Cow", true); //expecting happy - get happy
string sadDirect = testDirect.HappyMethod("Cow", false); //expecting not happy - get not happy
string defaultDirect = testDirect.HappyMethod("Cow"); //expecting happy (default) get happy
//unity
var testUnity = ServiceLocator.Current.GetInstance<ITestOptional>();
string happyUnity = testUnity.HappyMethod("Cow", true); //expecting happy - get happy
string sadUnity = testUnity.HappyMethod("Cow", false); //expecting not happy - get not happy
string defaultUnity = testUnity.HappyMethod("Cow"); //expecting happy (default) but get NOT happy.
当实现使用true时,Unity对象使用false作为可选参数的任何想法?
答案 0 :(得分:1)
ServiceLocator.Current.GetInstance<ITestOptional>();
返回编译类型ITestOptional
,因此编译器将调用testUnity.HappyMethod("Cow");
来使用接口中指定的默认值。
类似地new TestingOptional();
返回编译时TestingOptional
,编译器将从类中选择默认值。
可能的解决方案(没有调整期望/不使用不同的默认值):您可以使用Unity直接解析该类型而不是解析interfce(有时对测试有用):
var directViaContainer = container.Resolve<TestingOptional>();
附注:在实现接口的类中重新定义默认值不是上帝的做法 - 你经常会陷入这个令人困惑的代码。
答案 1 :(得分:1)
这与Unity无关。这就是C#编译器的工作原理。编译器在编译时填写可选参数。在第一个示例中,您在具体类型上调用HappyMethod
方法,并且该可选属性标记为true
,因此C#编译器将为您填写true。但是在第二个例子中,C#编译器不知道实现是否存在,因此它将查看接口的定义。猜猜看:该界面标有false
。
答案 2 :(得分:0)
在您的第一个示例中,您的testDirect
是TestingOptional
类型的实例,您可以使用它指定的默认参数值HappyMethod
直接调用其true
重载。
在第二个示例中,您的testUnity
是ITestOptional
类型的实例,并且您调用其HappyMethod
指定了不同的默认参数值false
。
这与您创建这些实例的方式无关。如果你做了,你会发现同样的事情:
ITestOptional x = new TestingOptional();
x.HappyMethod("Cow");