30

好吧,我知道你在想什么,“为什么要写一个你不想让人们使用的方法?” 对?

好吧,简而言之,我有一个需要序列化为 XML 的类。为了XmlSerializer发挥它的魔力,类必须有一个默认的空构造函数:

public class MyClass
{
  public MyClass()
  {
    // required for xml serialization
  }
}

所以,我需要它,但我不希望人们使用它,那么是否有任何属性可用于将方法标记为“请勿使用”?

我正在考虑使用Obsolete属性(因为这可以停止构建),但这似乎有点“错误”,还有其他方法可以做到这一点,还是我需要继续咬紧牙关?:)

更新

好的,我接受了基思的回答,因为我心里想,我完全同意。这就是为什么我首先提出这个问题,我不喜欢拥有Obsolete属性的概念。

然而...

还有一个问题,当我们收到智能感知通知时,理想情况下,我们想破坏构建,那么有什么办法可以做到这一点?也许创建一个自定义属性?

这里创建了更集中的问题。

4

13 回答 13

27

您可以使用:

[System.ComponentModel.EditorBrowsable(System.ComponentModel.EditorBrowsableState.Never)]

这样它就不会出现在 IntelliSense 中。如果消费者仍然想使用它,他们可以使用它,但它不会那么容易被发现。

尽管如此,基思关于过度设计的观点仍然成立。

于 2008-08-26T22:10:52.493 回答
16

如果一个类是[Serialisable](即它可以根据需要在该位置复制),则需要无参数构造函数来反序列化。

我猜你想强制你的代码访问将你的属性的默认值传递给参数化的构造函数。

基本上,您是说XmlSerializer复制然后设置属性是可以的,但您不希望自己的代码这样做。

在某种程度上,我认为这是过度设计。

只需添加 XML 注释,详细说明哪些属性需要初始化(以及要初始化什么)。

不要使用[Obsolete],因为它不是。为真正过时的方法保留它。

于 2008-08-26T11:58:55.040 回答
7
throw new ISaidDoNotUseException();
于 2008-08-26T22:23:47.190 回答
3

实际上,我倾向于不同意所有提倡使用的人,ObsoleteAttribute因为 MSDN 文档说:

将元素标记为过时会通知用户该元素将在产品的未来版本中删除。

因为 XML 序列化的通用构造函数不应该从应用程序中删除,所以我不会应用它,以防万一维护开发人员不熟悉 XML 序列化的工作原理。

我实际上一直在使用Keith 的方法,只是注意到构造函数用于 XML 文档中的序列化,以便它显示在 Intellisense 中。

于 2008-08-26T12:34:50.240 回答
2

我读了标题并立即想到“过时的属性”。怎么样

    /// <summary>
    /// do not use
    /// </summary>
    /// <param name="item">don't pass it anything -- you shouldn't use it.</param>
    /// <returns>nothing - you shouldn't use it</returns>
    public bool Include(T item) { 
    ....
于 2008-08-26T11:12:47.317 回答
2

您可以构建自己的Attribute派生类,例如NonCallableAttribute限定方法,然后在构建/CI 代码分析任务中添加检查以监控是否有任何代码正在使用这些方法。

在我看来,你确实不能强迫开发人员不使用该方法,但你可以尽快发现有人违反规则并修复它。

于 2008-08-26T22:18:32.867 回答
1

将您的可序列化对象与域对象分开。

于 2008-08-26T23:45:25.013 回答
0

ObsoleteAttribute可能会在您的情况下工作 - 如果使用该方法,您甚至可能导致构建中断。

由于过时警告发生在编译时,并且由于序列化所需的反射发生在运行时,将方法标记为过时不会破坏序列化,但会警告开发人员该方法不可用。

于 2008-08-26T11:13:06.240 回答
0

您正在寻找的是ObsoleteAttribute课程:

using System;

public sealed class App {
   static void Main() {      
      // The line below causes the compiler to issue a warning:
      // 'App.SomeDeprecatedMethod()' is obsolete: 'Do not call this method.'
      SomeDeprecatedMethod();
   }

   // The method below is marked with the ObsoleteAttribute. 
   // Any code that attempts to call this method will get a warning.
   [Obsolete("Do not call this method.")]
   private static void SomeDeprecatedMethod() { }
}
于 2008-08-26T11:13:41.793 回答
0

是的,有。

我写了这篇关于它的博客文章与设计师一起工作

这是代码:


public class MyClass
{
  [Obsolete("reason", true)]
  public MyClass()
  {
    // required for xml serialization
  }
}

于 2008-08-26T11:13:53.773 回答
0

我正在使用ObsoleteAttribute.

当然,您也可以发表一些评论。

如果可以的话,最后完全删除它(不必保持与旧东西的兼容性)。这是最好的方法。

于 2008-08-26T11:13:56.630 回答
0

哇,这个问题也困扰着我。

您还需要 NHibernate 的默认构造函数,但我想强制人们不要使用 C# 3.0 对象初始值设定项,以便类通过构造函数代码。

于 2008-08-26T11:41:54.253 回答
0

已经有很多很好的答案了。但我认为最好的选择是使用可以使用参数化构造函数的序列化程序。它不是您需要的序列化程序,但例如 Entity Framework Core 知道如何使用参数化构造函数。

实体框架核心文档:

如果 EF Core 找到参数名称和类型与映射属性匹配的参数化构造函数,则它将改为使用这些属性的值调用参数化构造函数,并且不会显式设置每个属性。

于 2020-02-06T14:45:41.173 回答