- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一种情况,我想将 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 中可用的动态类型的忠实粉丝)。它肯定不像动态解决方案那样干净/可读,但如果您不想抛出异常,它可能是可行的方法。
编辑:正如@arbiter 指出的那样,“这仅对 native .net 动态对象有效。这不适用于 IDispatch。”
关于C# 4.0,检测方法是否缺失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1071258/
我想了解 Ruby 方法 methods() 是如何工作的。 我尝试使用“ruby 方法”在 Google 上搜索,但这不是我需要的。 我也看过 ruby-doc.org,但我没有找到这种方法。
Test 方法 对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。 object.Test(string) 参数 object 必选项。总是一个
Replace 方法 替换在正则表达式查找中找到的文本。 object.Replace(string1, string2) 参数 object 必选项。总是一个 RegExp 对象的名称。
Raise 方法 生成运行时错误 object.Raise(number, source, description, helpfile, helpcontext) 参数 object 应为
Execute 方法 对指定的字符串执行正则表达式搜索。 object.Execute(string) 参数 object 必选项。总是一个 RegExp 对象的名称。 string
Clear 方法 清除 Err 对象的所有属性设置。 object.Clear object 应为 Err 对象的名称。 说明 在错误处理后,使用 Clear 显式地清除 Err 对象。此
CopyFile 方法 将一个或多个文件从某位置复制到另一位置。 object.CopyFile source, destination[, overwrite] 参数 object 必选
Copy 方法 将指定的文件或文件夹从某位置复制到另一位置。 object.Copy destination[, overwrite] 参数 object 必选项。应为 File 或 F
Close 方法 关闭打开的 TextStream 文件。 object.Close object 应为 TextStream 对象的名称。 说明 下面例子举例说明如何使用 Close 方
BuildPath 方法 向现有路径后添加名称。 object.BuildPath(path, name) 参数 object 必选项。应为 FileSystemObject 对象的名称
GetFolder 方法 返回与指定的路径中某文件夹相应的 Folder 对象。 object.GetFolder(folderspec) 参数 object 必选项。应为 FileSy
GetFileName 方法 返回指定路径(不是指定驱动器路径部分)的最后一个文件或文件夹。 object.GetFileName(pathspec) 参数 object 必选项。应为
GetFile 方法 返回与指定路径中某文件相应的 File 对象。 object.GetFile(filespec) 参数 object 必选项。应为 FileSystemObject
GetExtensionName 方法 返回字符串,该字符串包含路径最后一个组成部分的扩展名。 object.GetExtensionName(path) 参数 object 必选项。应
GetDriveName 方法 返回包含指定路径中驱动器名的字符串。 object.GetDriveName(path) 参数 object 必选项。应为 FileSystemObjec
GetDrive 方法 返回与指定的路径中驱动器相对应的 Drive 对象。 object.GetDrive drivespec 参数 object 必选项。应为 FileSystemO
GetBaseName 方法 返回字符串,其中包含文件的基本名 (不带扩展名), 或者提供的路径说明中的文件夹。 object.GetBaseName(path) 参数 object 必
GetAbsolutePathName 方法 从提供的指定路径中返回完整且含义明确的路径。 object.GetAbsolutePathName(pathspec) 参数 object
FolderExists 方法 如果指定的文件夹存在,则返回 True;否则返回 False。 object.FolderExists(folderspec) 参数 object 必选项
FileExists 方法 如果指定的文件存在返回 True;否则返回 False。 object.FileExists(filespec) 参数 object 必选项。应为 FileS
我是一名优秀的程序员,十分优秀!