【问题标题】:Providing Inherited Static Properties (conceptually)提供继承的静态属性(概念上)
【发布时间】:2009-01-07 21:47:50
【问题描述】:

我有一个 C# 基类,我要在每个类型(而不是每个实例)的基础上关联信息。本质上,我希望所有子类都呈现一个 Icon 和一个代表该类型的 FriendlyName。我希望必须创建一个类型实例来获取此信息,并且我想要求所有子类都提供此信息。理想情况下,它将位于基类派生的接口中。

我尝试使用类属性,但它需要一个常量值,所以虽然我可以设置 FriendlyName,但我无法设置图标,而且我看不到任何方法来使属性成为必需,所以没有它的子类可以侥幸逃脱(直到运行时)。

我在基础上添加了一个静态属性,孩子们可以隐藏,但这有点丑陋,基础的值真的很荒谬。它不知道给孩子取什么名字。我可以在 Property 中进行 base throw,但同样,直到运行时才会被捕获。

有人对我如何实现这样的事情有任何想法吗?有没有我错过的模式?也鼓励任何开箱即用的想法。

编辑:真正需要的是能够沿继承树要求类属性并能够使用嵌入式资源来设置这些属性。将返回的所有信息实际上都是静态的并且在编译时是已知的。我只是想不出一种很好地暴露它的方法。

编辑 2:这是我需要的更具体的示例:

假设我有一个基类:

abstract class Vehicle { ... }

然后我有两个孩子:

class Car : Vehicle { ... }

class Truck : Vehicle { ... }

我希望能够获得一个代表“汽车”或“卡车”的图标,而不必创建一个实例(例如 Car.Icon),因为给定类型的所有车辆都将具有相同的图标。

我还想确保所有车辆派生类型公开相同的方式来获取此图标,以防将来有人出现并添加新类

class Airplane : Vehicle  { ... }

编辑 3: 为什么我需要这个?好吧,我们有一个可以使用插件的应用程序。插件由一个类型定义,当类型被加载时,我们向用户显示一个图标和名称。当他们单击该图标时,它会创建该类型的实例(并为他们提供一个用于命名实例的对话框等)。我不需要或不想必须创建该类型的实例来获取图标。

【问题讨论】:

    标签: c# inheritance


    【解决方案1】:

    如果您想绝对要求孩子实现这一点,那么我认为这样做的唯一方法是将基类抽象化,并公开实例属性以返回图标和友好名称。

    这些将是抽象的,而不是虚拟的,因此您强制派生类实现。我知道它不干净,因为它是更好地存储在类型级别的信息,但这是我可以看到在编译时强制执行此要求的唯一方法。

    【讨论】:

    • 是的,这就是我走过的路线,但我只是觉得这样做很脏。必须创建一个实例来获取信息会增加其使用方式的复杂性。
    【解决方案2】:

    我认为你可能错过的一点是你不能重写静态属性是有充分理由的——也就是说,当你编写代码来调用它时,你没有实例,所以编译器会那时静态链接它——如果你需要多态性,你需要使用一个实例让运行时确定调用哪个版本的方法。

    编辑:(响应您的 EDIT2)

    你想从什么场景调用它?

    如果你想在一个实例上显示你的图标,你已经有了一个实例,那么为什么不将它作为实例上的一个属性(因为毕竟,有人可能会覆盖你的 Car 来创建一个SportsCar 并想要一个不同的图标)——实际上你是在要求你的对象的一个​​属性,尽管它与概念模型相匹配(所以它不是轮子的数量、最大速度等;而是一些东西将其可视化给最终用户)

    EDIT2:(响应您的 EDIT3)

    我要做的方法是使用属性来识别哪个嵌入式资源用作相应类型的图标(因此您不需要实例),并使用反射来读取值.您可以定义自己的自定义属性,或查看ToolboxItemAttribute可能有用。

    【讨论】:

    • 不,我没有错过 - 这就是为什么标题包含“概念上”的原因。我知道我不能继承静态,但我需要这种概念性行为。
    • 分离出抽象的只读属性,或者可能是一个接口:)
    • 是的,但是对于属性或接口,您仍然必须拥有派生类的实例才能获取该信息。 OP 试图避免创建一个实例只是为了获取此类型的所有对象都相同的信息。
    • 把问题转过来——你如何称呼派生版本,而不是基础实现? -- 你能做的最好的事情就是隐藏父级,但你总是会指定要使用的确切类型的版本。
    • 我会在插件场景中使用它。该图标用于插件类型。当用户点击它时,它会创建一个实例。在他们单击之前,我不需要(或想要)实例,但我确实需要图标(和名称)。
    【解决方案3】:

    也许您可以做的是定义一个属性,用于在您的插件系统中注册该对象。

    这样,您将强制类的开发人员分配属性以便在您的插件系统中工作。

    也许您可以使用ToolboxBitmapAttribute 之类的方法,您可以在其中将找到的图像设置到您的 dll 的资源中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-16
      • 2017-04-21
      • 1970-01-01
      • 2016-10-10
      • 2018-07-07
      • 2020-01-25
      相关资源
      最近更新 更多