- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在研究如何定义 ParameterInfo.IsOptional
(我正在向内部 IOC 框架添加默认参数支持),在我看来,当为 true 时,无法保证ParameterInfo.DefaultValue
(或者实际上ParameterInfo.RawDefaultValue
)实际上是要应用的默认值。
如果你看MSDN example given for IsOptional
,在 IL 中似乎可以定义一个可选参数,但不提供默认值(假设必须显式提供 ParameterAttributes.HasDefault
)。 IE。可能会导致参数类型为 Int32
、ParameterInfo.IsOptional
为 true,但 ParameterInfo.DefaultValue
为 null 的情况。
我的语言是 C#,因此我可以研究编译器将要做的事情。基于此,我可以进行如下简单的测试(parameter
这里是一个 ParameterInfo
实例,该方法旨在返回一个实例,用作运行时参数参数):
if(no_config_value)
{
if(!parameter.IsOptional) throw new InvalidOperationException();
//it's optional, so read the Default
return parameter.DefaultValue;
}
else
return current_method_for_getting_value();
但我认为某些语言(我希望在 IL 级别上做到这一点,而不是仅仅基于某个特定编译器的功能)可以将责任归咎于调用者确定要使用的默认值,如果是这样,则需要按顺序使用 default(parameter.ParameterType)
。
这就是它变得更有趣的地方,因为如果没有默认值,则 DefaultValue
显然是 DBNull.Value
(根据 the documentation for RawValue
)。如果参数的类型为 object
且 IsOptional==true
,那就不好了!
经过更多挖掘,我希望解决此问题的可靠方法是物理读取 ParameterInfo.Attributes
成员,首先单独读取位标志检查ParameterAttributes.Optional
并然后检查ParameterAttributes.Default
。仅当两者都存在时,读取ParameterInfo.DefaultValue
才是正确的。
我将开始围绕此进行编码和编写测试,但我希望有人具有更多 IL 知识,可以证实我的怀疑,并希望确认这对于任何基于 IL 的都是正确的语言(从而避免需要模拟不同语言的库负载!)。
最佳答案
我的问题的简短答案是否定的 - 只是因为 IsOptional
为 true 并不意味着 DefaultValue
实际上包含真正的默认值。我在问题文本中进一步的假设是正确的(.Net 文档确实以一种迂回的方式解释了这一点)。本质上,如果存在默认值,那么调用者应该使用它,否则调用者应该提供自己的默认值。参数的Attributes
用于确定是否存在默认值。
这就是我所做的。
假设存在以下方法:
/* wrapper around a generic FastDefault<T>() that returns default(T) */
public object FastDefault(Type t) { /*elided*/ }
然后给出一个特定的参数和提供的参数值的字典(来自配置):
public object GetParameterValue(ParameterInfo p, IDictionary<string, object> args)
{
/* null checks on p and args elided - args can be empty though */
object argValue = null;
if(args.TryGetValue(p.Name, out argValue))
return argValue;
else if(p.IsOptional)
{
//now check to see if a default is supplied in the IL with the method
if((p.Attributes & ParameterAttributes.HasDefault) ==
ParameterAttributes.HasDefault)
return p.DefaultValue; //use the supplied default
else
return FastDefault(p.ParameterType); //use the FastDefault method
}
else //parameter requires an argument - throw an exception
throw new InvalidOperationException("Parameter requires an argument");
}
然后我在构造函数和方法上测试了这个逻辑,如下所示:
public class Test
{
public readonly string Message;
public Test(string message = "hello") { Message = message; }
}
I.E,除了可选参数之外还提供了默认值(程序正确地落入到达 ParameterInfo.DefaultValue
的分支)。
然后,在回答我问题的另一部分时,我意识到在 C# 4 中我们可以使用 OptionalAttribute
生成一个可选参数没有默认值:
public class Test2
{
public readonly string Message;
public Test2([OptionalAttribute]string message) { Message = message; }
}
程序再次正确地落入执行 FastDefault
方法的分支。
(在这种情况下,C# 也将使用类型的默认值作为此参数的实参)
我认为这涵盖了所有内容 - 它在我尝试过的所有内容上都运行良好(我很高兴尝试让重载解析感觉正确,因为我的 IOC 系统总是使用等效的命名参数 - 但 C# 4 规范对此有所帮助)。
关于.net - 默认参数和反射 : if ParameterInfo. IsOptional 那么DefaultValue总是可靠的吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9977530/
他们两个听起来很相似。来自 msdn: ParameterInfo.IsOptional Gets a value indicating whether this parameter is optio
这是How do I get default values of optional parameters?的后续问题 来自documentation, DefaultValue : Gets a va
我在谷歌搜索时在 Stack Overflow 中找到了这个问题,但它已被删除。所以我再次列出这个问题。 由于我在BCL中找不到LcidAttribute或RetvalAttribute,我猜测C#没
我想知道是否可以根据 ParameterInfo 确定方法中的参数是否是 this object me 类型的参数?我知道你可以是 IsOut 和 IsRef 等 谢谢。 最佳答案 您不会在它们扩展的
如何确定 ParameterInfo 是否为返回参数? 我编写了下面的函数,但我担心我可能会遗漏一些东西: public bool IsReturnParameter(ParameterInfo pa
实际上我没有什么问题可以更容易地理解我要问的问题我必须先展示我的代码。 public static void Main(string[] args) { CustomClass customC
有没有办法检查 ParameterInfo 是否是一个集合? 我试过这个: ConstructorInfo[] constructorInfos = typeof(T).GetConstructors
对于我正在处理的应用程序,我试图显示一个模板,该模板将显示(运行时确定的)方法的参数是什么样的。我正在处理的测试用例应该显示“PERSON = (FIRST = first; LAST = last)
我正在研究如何定义 ParameterInfo.IsOptional (我正在向内部 IOC 框架添加默认参数支持),在我看来,当为 true 时,无法保证ParameterInfo.DefaultV
对我来说,它们是非常相似的结构。我希望有一种方法可以轻松地将一个转换为另一个。 我正在使用反射来施展魔法。我选择了使用参数化构造函数来创建一些用户选择的对象的路径,他们使用 UI 为参数填充这些对象的
好吧,我对 ParameterInfo 的属性感到困惑类(class)。 不幸的是,文档不是很清楚:示例展示了如何构建方法,但没有展示这些方法在 C# 中的外观。 甘蔗有人详细介绍了这些属性: Def
我正在编写一个自动化 SQLCLR 部署工具,并使用反射来发现必须声明的过程和函数。因此,我使用这样的代码来构建部署汇编方法所需的 T-SQL: ... if (p.ParameterType ==
我正在尝试验证参数既是输出参数又是扩展接口(interface) (ICollection)。反射 api 似乎不想给我参数的“真实”类型,只有最后带有“&”的参数不会在 IsAssignableFr
我是一名优秀的程序员,十分优秀!