像静态一样调用类的常量属性?

发布于 2024-11-02 21:00:50 字数 1790 浏览 4 评论 0原文

我有一个抽象基类

public class Base
{
  public abstract String Info { get; }
}

和一些孩子。

public class A : Base
{
  public override String Info { get { return "A does ..."; } }
}

public class B : Base
{
  public override String Info { get { return "B does ..."; } }
}

这只是一个常量,但我想确保使用 Base 所有类都实现它。

现在,我有时没有对象实例,但想要访问 A.Info - 这是不可能的,因为它是实例属性。

除了在实例和静态级别上实现相同的属性之外,还有其他方法吗?这感觉像是重复的违反 DRY 编程风格的行为。


新编辑:我现在看到这两个解决方案:

public class Base
{
  public abstract String ClassInfo { get; }
}

public class A : Base
{
  public override String ClassInfo { get { return Info; } }

  public static String Info { get { return "A does ..."; } }
}

public class B : Base
{
  public override String ClassInfo { get { return Info; } }

  public static String Info { get { return "In B we do ..."; } }
}

有了这个,我可以处理Base类型的任何object,例如object.ClassInfo 但也使用我的工厂中硬编码的值,例如 if(A.Info) return new A()。但我必须在每个类中为相同的信息实现两个属性。

另一方面:

public class Base
{
  public abstract String ClassInfo { get; }

  public static String GetClassInfo<T>() where T : BaseControl, new()
  {
    T obj = new T();
    return obj.ClassInfo;
  }
}

public class A : Base
{
  public override String ClassInfo { get { return "text A"; } }
}

public class B : Base
{
  public override String ClassInfo { get { return "text B"; } }    
}

由于抽象的Base,它确保ClassInfo始终被实现。使用 obj.ClassInfoBase.GetClassInfo() 进行调用是可以的。但是这样一来,Base 的每个子级都必须有一个不带参数的默认构造函数,并且我们会因为不必要的创建实例而降低性能。

还有其他想法吗?您更喜欢哪一个?为什么?

I got an abstract base class

public class Base
{
  public abstract String Info { get; }
}

and some children.

public class A : Base
{
  public override String Info { get { return "A does ..."; } }
}

public class B : Base
{
  public override String Info { get { return "B does ..."; } }
}

This is mere a constant but I want to make sure using Base that all classes implement it.

Now I sometimes do not have an object instance but want to access A.Info - this is not possible due it is a instance property.

Is there another way than implementing the same property on instance AND on static level? That would be feel like a duplicate violating DRY programming style.


NEW EDIT: I now see this two solutions:

public class Base
{
  public abstract String ClassInfo { get; }
}

public class A : Base
{
  public override String ClassInfo { get { return Info; } }

  public static String Info { get { return "A does ..."; } }
}

public class B : Base
{
  public override String ClassInfo { get { return Info; } }

  public static String Info { get { return "In B we do ..."; } }
}

With this I can do with any object of type Base something like object.ClassInfo but also use the value in my factory hardcoded like if(A.Info) return new A(). But I have to implement two properties for the same information in every class.

On the other hand:

public class Base
{
  public abstract String ClassInfo { get; }

  public static String GetClassInfo<T>() where T : BaseControl, new()
  {
    T obj = new T();
    return obj.ClassInfo;
  }
}

public class A : Base
{
  public override String ClassInfo { get { return "text A"; } }
}

public class B : Base
{
  public override String ClassInfo { get { return "text B"; } }    
}

Due to the abstract Base it is made sure that ClassInfo is always implemented. Calls with obj.ClassInfo and Base.GetClassInfo<A>() are okay. But with this every child of Base must have a default constructor without arguments and we loose performance with the unneccessary created instance.

Is there any other idea? Which one would you prefer and why?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

听你说爱我 2024-11-09 21:00:50

如果您需要静态属性的特定返回结果,那么最好选择

a) 实例属性
2) 属性

在你已经给出的示例中,你有一个 Base 实例,这意味着你可以将实例属性设为虚拟:

public class Base
{
    public virtual string Info { get { return "From Base"; } }
}

public class A : Base
{
    public override string Info { get { return "From A"; } }
}

如果你想走属性路线,你可以定义它是这样的:

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InfoAttribute : Attribute
{
    public InfoAttribute(string info) { this.Info = info; }

    public string Info { get; private set; }
}

[InfoAttribute(Info = "From Base")]
public class Base
{
    public string GetInfo()
    {
        var attr = GetType()
            .GetCustomAttributes(typeof(InfoAttribute), true)
            .FirstOrDefault();

        return (attr == null) ? null : attr.Info;
    }
}

[InfoAttribute(Info = "From A")]
public class A : Base { }

如果您想将其作为静态函数调用来调用,您可以进行以下更改:

public static string GetInfo(Base instance)
{
    var attr = instance.GetType()
        .GetCustomAttributes(typeof(InfoAttribute), true)
        .FirstOrDefault();

    return (attr == null) ? null : attr.Info;
}

然后将其调用为:Base.GetInfo(instance);。总而言之,不太优雅!

If you need specific return results of your static properties, you're better of either

a) Instance properties
2) Attributes

In the example you've already given, you've got an instance of Base, which means you can just make the instance property virtual:

public class Base
{
    public virtual string Info { get { return "From Base"; } }
}

public class A : Base
{
    public override string Info { get { return "From A"; } }
}

If you wanted to go the attribute route, you define it as such:

[AttributeUsage(AttributeTargets.Class, Inherited = true)]
public class InfoAttribute : Attribute
{
    public InfoAttribute(string info) { this.Info = info; }

    public string Info { get; private set; }
}

[InfoAttribute(Info = "From Base")]
public class Base
{
    public string GetInfo()
    {
        var attr = GetType()
            .GetCustomAttributes(typeof(InfoAttribute), true)
            .FirstOrDefault();

        return (attr == null) ? null : attr.Info;
    }
}

[InfoAttribute(Info = "From A")]
public class A : Base { }

If you wanted to call it as a static function call, you could make this change:

public static string GetInfo(Base instance)
{
    var attr = instance.GetType()
        .GetCustomAttributes(typeof(InfoAttribute), true)
        .FirstOrDefault();

    return (attr == null) ? null : attr.Info;
}

And then call it as: Base.GetInfo(instance);. All in all, not very elegant!

泪是无色的血 2024-11-09 21:00:50

这是不可能的。
static 成员不能是虚拟的或抽象的。

您应该创建一个抽象实例属性。

This is not possible.
static members cannot be virtual or abstract.

You should make an abstract instance property.

腹黑女流氓 2024-11-09 21:00:50

静态数据无法被覆盖。如果您确实想做类似的事情,那么您需要一个在基类中为虚拟的实例属性,该属性在子类中被覆盖。

Statics can't be overridden. If you truly want to do something like that, you'd want an instance property that is virtual in the base that gets overridden in the subclasses.

孤云独去闲 2024-11-09 21:00:50

编译通过了吗?我不这么认为。静态不能标记为覆盖、虚拟或抽象。

Does it compiled? I don't think so. Static cannot be marked as override, virtual or abstract.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文