gpt4 book ai didi

C# 4.0,检测方法是否缺失

转载 作者:太空狗 更新时间:2023-10-29 20:04:02 25 4
gpt4 key购买 nike

我有一种情况,我想将 LinePragmas 添加到 CodeDom 对象。但有些代码 dom 对象具有 LinePragma 属性,有些则没有。

所以我想知道是否可以使用 dynamic 关键字来检测对象上是否存在该属性(不抛出异常),如果存在则添加 pragma。这是我目前的方法:

public static T SetSource<T>(this T codeObject, INode sourceNode)
where T : CodeObject
{
codeObject.UserData["Node"] = sourceNode.Source;
dynamic dynamicCodeObject = codeObject;

// How can I not throw an exception here?
if (dynamicCodeObject.LinePragma != null)
{
dynamicCodeObject.LinePragma = new CodeLinePragma(
sourceNode.Source.Path.AbsoluteUri,
sourceNode.Source.StartLine);
}

return codeObject;
}

更新:我采用的解决方案是添加一个名为 Exists() 的扩展方法。我在这里写了一篇关于它的博客文章: Member Exists Dynamic C# 4.0

主要目的是创建一个扩展方法,该方法返回一个实现 DynamicObject 的 TryGetMember 的对象。它使用反射然后返回 true 或 false。这允许您编写如下代码:

object instance = new { Foo = "Hello World!" };
if (instance.Reflection().Exists().Foo)
{
string value = instance.Reflection().Call().Foo;
Console.WriteLine(value);
}

最佳答案

您无需使用 C# 4.0 的动态特性即可检测对象是否具有属性 - 而不是使用已经存在一段时间的反射特性(我至少知道 .NET 2.0,不确定 < 2.0)

PropertyInfo info = codeObject.getType().GetProperty(
"LinePragma",
BindingFlags.Public | BindingFlags.Instance
)

如果对象不具有该属性,则 GetProperty() 将返回 null。您可以对字段 ( GetField() ) 和方法 ( GetMethod() ) 执行类似操作。

不仅如此,一旦你有了 PropertyInfo,你就可以直接使用它来做你的设置:

info.SetValue(codeObject, new CodeLinePragma(), null);

如果您不确定该属性是否有 set 方法,您可以采取更安全的方法:

MethodInfo method = info.GetSetMethod();
if(method != null)
method.Invoke(codeObject, new object[]{ new CodeLinePragma() });

这还为您带来了额外的好处,即在动态调用的查找开销方面性能更高(无法找到该语句的引用,所以我将其 float 在那里)。

我想这并没有直接回答您的问题,而是实现相同目标的替代解决方案。我还没有真正使用过#4.0 功能(尽管我是 Ruby 中可用的动态类型的忠实粉丝)。它肯定不像动态解决方案那样干净/可读,但如果您不想抛出异常,它可能是可行的方法。

编辑:正如@a​​rbiter 指出的那样,“这仅对 native .net 动态对象有效。这不适用于 IDispatch。”

关于C# 4.0,检测方法是否缺失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1071258/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com