C# 如何在不生成异常的情况下检查COM属性或方法是否存在?

C# 如何在不生成异常的情况下检查COM属性或方法是否存在?,c#,com,.net-3.5,C#,Com,.net 3.5,我正在处理一些遗留代码,这些代码创建一个包含属性和/或方法名称的字符串列表,然后尝试将这些属性或方法应用于COM对象。COM对象的属性或方法不能保证存在,它可能是属性或方法,我不知道是哪个 此时,如果属性或方法不存在,它将被捕获为COM异常。这导致性能不佳。我试图找到一种方法来检查COM对象中是否存在属性或方法,而不生成异常,以便在尝试应用它之前检查它是否存在 使用GetType返回System.com_对象类型。在System.com_对象上使用GetProperty不起作用,因为这是确切的运

我正在处理一些遗留代码,这些代码创建一个包含属性和/或方法名称的字符串列表,然后尝试将这些属性或方法应用于COM对象。COM对象的属性或方法不能保证存在,它可能是属性或方法,我不知道是哪个

此时,如果属性或方法不存在,它将被捕获为COM异常。这导致性能不佳。我试图找到一种方法来检查COM对象中是否存在属性或方法,而不生成异常,以便在尝试应用它之前检查它是否存在

使用GetType返回System.com_对象类型。在System.com_对象上使用GetProperty不起作用,因为这是确切的运行时类型,而不是它的派生类型。相反,我必须调用member,如果成员不存在,它会创建一个异常。有人有更好的方法吗

我现在在.net3.5工作。迁移到.NET4目前不是一个选项,但是如果新的语言特性提供了更好的解决问题的方法,我仍然对.NET4中的解决方案感兴趣

public static bool CheckIfComPropertyOrMethodExists<T1>(T1 objectToCheck, string propertyOrMethodName)
{
    if (CheckIfComPropertyExists(objectToCheck, propertyOrMethodName) == false & CheckIfComMethodExists(objectToCheck, propertyOrMethodName) == false) {
        return false;
    }
    {
        return true;
    }
}

public static bool CheckIfComPropertyExists<T1>(T1 objectToCheck, string propertyName)
{
    return objectToCheck.GetType().InvokeMember(propertyName, BindingFlags.GetProperty, null, objectToCheck, null) != null;
}

public static bool CheckIfComMethodExists<T1>(T1 objectToCheck, string methodName)
{
    return objectToCheck.GetType().GetMethod(methodName, BindingFlags.Public | BindingFlags.Instance) != null;
}
publicstaticboolcheckifcompropertyormethodexists(T1 objectToCheck,stringpropertyormethodname)
{
if(CheckIfComPropertyExists(objectToCheck,propertyOrMethodName)==false&CheckIfComMethodExists(objectToCheck,propertyOrMethodName)==false){
返回false;
}
{
返回true;
}
}
公共静态bool CheckIfComPropertyExists(T1 objectToCheck,string propertyName)
{
返回objectToCheck.GetType().InvokeMber(propertyName,BindingFlags.GetProperty,null,objectToCheck,null)!=null;
}
公共静态bool CheckIfComMethodExists(T1 objectToCheck,string methodName)
{
返回objectToCheck.GetType().GetMethod(methodName,BindingFlags.Public | BindingFlags.Instance)!=null;
}
迄今为止有用的文章


COM类很可能还实现了IDispatch接口。然后,您可以使用其GetIDsOfNames检查类中是否存在成员

这里有人从C#叫它:


谢谢您的回答。我认为GetIDsOfNames会解决这个问题。我很快就会接受你的答复。我想知道你是否介意用一个例子来扩展你的答案,因为我很难理解。我正在尝试访问Microsoft.Office.Interop.Excel的成员。如果我不知道要应用GetIDsOfNames的类的底层类型,如何为类获取IDsofNames?我只有一个System.com_对象。这可能是Microsoft.Office.Interop.Excel NamspCe中的任何类型只要将COM对象强制转换为IDispatch,不管对象是什么类型,它都会确保实现IDispatch。如果成员不存在,GetIDsofNames会抛出DISP_E_UNKNOWNNAME COM异常。这意味着我仍然有同样的性能问题。有没有办法做到这一点?我尝试了以下方法,但没有成功。(六年后…)您可以使用[PreserveSig]属性标记GetIdsOfNames,让它直接返回HRESULT,而不会因错误情况引发异常。不要忘记过滤掉“FormatDrive”方法。