C# 接口、Unity 和可选参数
C# Interface, Unity, and Optional Parameter
希望有人能阐明这一点。我有一个带有可选参数的接口。我们使用统一。如果我尝试更改方法实现中的可选参数,它会直接起作用,但 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 作为可选参数吗?
您必须使用来自 IUnityContainer
实例的 Resolve<T>
方法。例如:
var testUnity = container.Resolve<ITestOptional>();
ServiceLocator.Current.GetInstance<ITestOptional>();
returns 编译类型 ITestOptional
,因此对 testUnity.HappyMethod("Cow");
的调用将由编译器转换为使用接口中指定的默认值。
类似地 new TestingOptional();
returns 编译时 TestingOptional
并且编译器将从 class.
中选择默认值
可能的解决方案(除了使用不同的默认值调整 expectations/not):您可以直接使用 Unity 解析该类型而不是解析接口(有时对测试有用):
var directViaContainer = container.Resolve<TestingOptional>();
旁注:在 class 实现接口时重新定义默认值并不是什么好事——您会经常遇到这种令人困惑的代码。
在您的第一个示例中,您的 testDirect
是类型 TestingOptional
的一个实例,您可以使用它指定的默认参数值 [=14] 直接调用它的 HappyMethod
重载=].
在您的第二个示例中,您的 testUnity
是类型 ITestOptional
的实例,您调用它的 HappyMethod
指定不同的默认参数值 false
。
这与您创建这些实例的方式无关。如果您这样做,您会观察到相同的结果:
ITestOptional x = new TestingOptional();
x.HappyMethod("Cow");
这与Unity无关。这就是 C# 编译器的工作方式。可选参数由编译器在 编译时 填充。在第一个示例中,您在具体类型上调用了 HappyMethod
方法,并且该可选属性标记为 true
,因此 C# 编译器将为您填写 true。然而,在第二个示例中,C# 编译器不知道实现的存在,所以它会查看接口的定义。猜猜是什么:该接口标有 false
.
希望有人能阐明这一点。我有一个带有可选参数的接口。我们使用统一。如果我尝试更改方法实现中的可选参数,它会直接起作用,但 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 作为可选参数吗?
您必须使用来自 IUnityContainer
实例的 Resolve<T>
方法。例如:
var testUnity = container.Resolve<ITestOptional>();
ServiceLocator.Current.GetInstance<ITestOptional>();
returns 编译类型 ITestOptional
,因此对 testUnity.HappyMethod("Cow");
的调用将由编译器转换为使用接口中指定的默认值。
类似地 new TestingOptional();
returns 编译时 TestingOptional
并且编译器将从 class.
可能的解决方案(除了使用不同的默认值调整 expectations/not):您可以直接使用 Unity 解析该类型而不是解析接口(有时对测试有用):
var directViaContainer = container.Resolve<TestingOptional>();
旁注:在 class 实现接口时重新定义默认值并不是什么好事——您会经常遇到这种令人困惑的代码。
在您的第一个示例中,您的 testDirect
是类型 TestingOptional
的一个实例,您可以使用它指定的默认参数值 [=14] 直接调用它的 HappyMethod
重载=].
在您的第二个示例中,您的 testUnity
是类型 ITestOptional
的实例,您调用它的 HappyMethod
指定不同的默认参数值 false
。
这与您创建这些实例的方式无关。如果您这样做,您会观察到相同的结果:
ITestOptional x = new TestingOptional();
x.HappyMethod("Cow");
这与Unity无关。这就是 C# 编译器的工作方式。可选参数由编译器在 编译时 填充。在第一个示例中,您在具体类型上调用了 HappyMethod
方法,并且该可选属性标记为 true
,因此 C# 编译器将为您填写 true。然而,在第二个示例中,C# 编译器不知道实现的存在,所以它会查看接口的定义。猜猜是什么:该接口标有 false
.