【问题标题】:Prevent “Access to a static member of a type via a derived type” when deriving classes having structs with string constants在派生具有带有字符串常量的结构的类时,防止“通过派生类型访问类型的静态成员”
【发布时间】:2014-11-12 11:06:32
【问题描述】:

我将 ForgeRock REST API 实现封装在 C# 中。该实现是分层的。 ForgeRock 层有一个基础层,可针对他们的每个产品(如 OpenAM、OpenDJ 等)进行扩展。

API 层的一部分是 http 参数名称的定义(通常是对值的限制),我已经用 KnownParameter 类的层次结构解决了这些问题,每个类都有定义结构中参数的结构,每个结构都有一个 Name以及潜在的方法或嵌套 Values 结构限制或转换值。

代码库通常仅限于一种产品(以及祖先层:ForgeRock)。

从这个角度来看,我想避免 ReSharper 生成的“通过派生类型访问类型的静态成员”警告。

一方面,拥有相同名称的类确实有帮助(它们是相同的东西,只是从不同的命名空间角度来看,它可以编译并正常工作),另一方面:即使在将 ForgeRock.KnownParameters 重命名为 @987654326 之后@ReSharper 对此不满意。我觉得在这种受限的情况下,有这样的命名是可以的

如何在仍然受益于继承的同时避免该警告?

示例代码(也 on-line with more URLs 引用正确的文档位)分为四部分。

Main 程序出现 ReSharper 警告:

using System.Collections.Specialized;
using ForgeRock.OpenAM;

namespace AccessToAStaticMemberOfATypeViaADerivedType
{
    class Program
    {
        static void Main()
        {
            new NameValueCollection
            {
                {KnownParameters.PrettyPrint.Name, KnownParameters.PrettyPrint.Values.True},
                {KnownParameters.Action.Name, KnownParameters.Action.Values.Logout}
            };
        }
    }
}

ForgeRock 命名空间与基 KnownParameters 类:

namespace ForgeRock
{
    public class KnownParameters
    {
        public struct PrettyPrint
        {
            public const string Name = "_prettyPrint";

            public struct Values
            {
                public const string False = "false";
                public const string True = "true";
            }
        }
    }
}

ForgeRock.OpenAM 命名空间与 KnownParameters 类的后代。

namespace ForgeRock.OpenAM
{
    public class KnownParameters : ForgeRock.KnownParameters
    {
        public struct Action
        {
            public const string Name = "_action";

            public struct Values
            {
                public const string Logout = "logout";
            }
        }
    }
}

ForgeRock.OpenDJ 命名空间与 KnownParameters 类的后代。

namespace ForgeRock.OpenDJ
{
    public class KnownParameters : ForgeRock.KnownParameters
    {
        public struct QueryFilter
        {
            public const string Name = "_queryFilter";
        }
    }
}

【问题讨论】:

  • 你的例子不完整并没有帮助......如果你让这个例子独立起来真的很有帮助。请注意,您的示例根本没有显示 任何 继承......那么“仍然受益于继承”是什么意思?
  • 示例代码编译并显示继承:KnownParameters : ForgeRock.KnownParameters。我尝试将所有源代码放在一个文件中(包括各种命名空间),以便于理解。我应该把它们分开吗?
  • Gah - 我没有发现代码向下滚动。 IMO 有多个具有相同名称的类确实无济于事... 只是 给它们不同的名称会使这变得更简单(例如KnownOpenAMParametersKnownOpenDJParameters 等)。然后你可以在正确的时间参考正确的课程。
  • 没问题。我将代码拆分。具有相同名称的类一方面确实有帮助(它们是相同的东西,只是从不同的命名空间角度来看,它可以编译并且工作正常),另一方面 ReSharper 对此并不满意。我认为在这种受限的情况下,有这种命名是可以的。
  • 我认为在这种有限的情况下,有这种命名是可以的 所以只是禁用该警告? ReSharper 允许您出于某种原因禁用警告...

标签: c# resharper


【解决方案1】:

我认为在这种受限的情况下,有这样的命名是可以的。

好吧,我个人不同意。当同一个名称在程序中表示不同的事物时,通常会影响可读性——当这两个名称通过继承相关时,情况会更糟(IMO)。但如果你真的想用这种方式,有两种选择:

  • 当你想使用它的成员时,想办法指定ForgeRock.KnownParameters,例如

    new NameValueCollection
    {
        {ForgeRock.KnownParameters.PrettyPrint.Name, 
         ForgeRock.KnownParameters.PrettyPrint.Values.True},
        {KnownParameters.Action.Name,
         KnownParameters.Action.Values.Logout}
    };
    

    或者您可以使用using 别名:

    using BaseKnownParameters = ForgeRock.KnownParameters;
    ...
    new NameValueCollection
    {
        {BaseKnownParameters.PrettyPrint.Name, 
         BaseKnownParameters.PrettyPrint.Values.True},
        {KnownParameters.Action.Name,
         KnownParameters.Action.Values.Logout}
    };
    
  • 禁用 R# 警告,如果您很高兴通过 ForgeRock.OpenAM.KnownParameters 访问 ForgeRock.KnownParameters 的成员,例如使用 ASCIIEncoding.UTF8

顺便说一句,我建议使用静态类而不是结构。目前,有人可以这样写:

var x = new KnownParameters.PrettyPrint.Values();

...你想要那是合法的吗? (它不会使用静态类。)您也可以考虑使用枚举。

【讨论】:

  • 谢谢。这个ASCIIEncoding.UTF8 说服我改名。现在我需要为ForgeRock.KnownParameters 想一个更好的名字。我还不确定BaseKnownParameters 是否足够。还要感谢 structstatic class 的争论。即使子类是static classKnownParameters 仍然是class,那么您仍然可以使用var y = new KnownParameters();。你说得对,这是不可取的,这意味着我不能继承,必须找到好名字。
  • @JeroenPluimers-Binck:您可以使用带有受保护构造函数的抽象类作为起点……但是,我会完全避免在这里使用继承 :)
  • 我认为当前的构造已经足够接近 C# 边缘了 (;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-02
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 2018-07-14
  • 2017-11-27
相关资源
最近更新 更多