为啥 C++/CLI 编译器不为过时的属性调用生成警告?

Posted

技术标签:

【中文标题】为啥 C++/CLI 编译器不为过时的属性调用生成警告?【英文标题】:Why doesn't the C++/CLI compiler generate warnings for Obsolete property calls?为什么 C++/CLI 编译器不为过时的属性调用生成警告? 【发布时间】:2015-04-12 03:57:15 【问题描述】:

我从一些 C++/CLI 代码中引用了第 3 方 .NET 库。我的 C++/CLI 调用代码正在使用 Obsolete 属性引用已在 C# 库中标记为过时的属性:

// C# External library code
using System;
namespace ExternalLibrary

    public class Dependency
    
        [Obsolete("Please use the new version.")]
        public static bool IsInitialized
        
            get  return true; 
        
    

但是,当我编译使用该属性的 C++/CLI 调用代码时,即使我将警告级别设置为 /Wall EnableAllWarnings,它也不会生成任何过时/弃用的警告(例如 C4947)。

如果我从 C# 代码中引用相同的 API,我会收到预期的 CS0618 警告,告诉我该属性已过时,但是当我编译 C++/CLI 代码时,我没有收到任何过时或弃用警告。

// C# Calling code (in another assembly)
namespace CalledFromCSharp

    public class CSharpCode
    
        public static void CallingCode()
        
            // Generates warning CS0618:
            //   'ExternalLibrary.Dependency.IsInitialized' is obsolete:
            //   'Please use the new version.'
            bool initialized = ExternalLibrary.Dependency.IsInitialized;
        
    

// C++/CLI Calling code (also in another assembly)
#pragma once
using namespace System;
namespace CppCode

    public ref class CalledFromCpp
    
        static void CallingCode()
        
            // NO OBSOLETE WARNING GENERATED
            bool isInitialized = ExternalLibrary::Dependency::IsInitialized;
        ;
    ;

这似乎发生在静态和非静态属性调用中。是否需要在我的 C++/CLI 项目(使用 Visual Studio 2013)中设置一些额外的东西才能显示适当的警告?还是有当前行为的原因?

【问题讨论】:

C++/CLI 永远不会产生 CS0618 警告:CS 表示 C#。它应该生成C4947,但看起来没有 VS2013 等效项。 好点!我编辑了原文以试图提高清晰度。 【参考方案1】:

Hmya,讨厌成为坏消息的承担者,但 C++/CLI 设计者对属性的处理方式不同。从他们的语法中可以明显看出,他们在许多选择中都倾向于“类似于 C++”的方法。最好通过修改你的代码 sn-p 来证明:

public ref class CalledFromCpp 
public:
    static property bool Foo 
        [Obsolete("This works")]
        bool get()  return false; 
    
    [Obsolete("This doesn't work")]
    static property bool Bar 
        bool get()  return false;  
    
    static void CallingCode() 
        bool test1 = CalledFromCpp::Foo;   // Yes
        bool test2 = CalledFromCpp::Bar;   // Nope
        bool test3 = ExternalLibrary::Dependency::IsInitialized;  // Nope
    
;

你不能在 C# 属性上做同样的事情,它不允许你在 getter 上应用 [Obsolete] 属性。没有解决方法。

【讨论】:

这似乎是一个 C# 错误...ObsoleteAttribute 类明确声明它可以与方法一起使用,并且 C# 确实允许将带有 AttributeUsage(AttributeTargets.Method) 的自定义属性应用于访问器。 ...因为ObsoleteAttribute 也被标记为AttributeTargets.Property,这看起来像是一个 C++/CLI 编译器错误/疏忽。

以上是关于为啥 C++/CLI 编译器不为过时的属性调用生成警告?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 C++ CLI 索引属性在 C# 中不起作用?

函数调用时的 C 到 C++ 错误

为啥 Xcode 不为静态库生成 dSYM

C++/CLI 为啥对托管不可见

为啥从独立函数生成的 pyplot 窗口与从事件处理程序调用的函数生成时的行为不同?

为啥 vector.push_back(System::Byte) 在 VC++ 14.29 (C++/CLI) 中不再编译