【问题标题】:Static interface equivalent C#静态接口等效 C#
【发布时间】:2015-06-10 15:36:42
【问题描述】:

我过去曾使用过单例,我知道这对于一些尝试解决静态界面问题的人来说是一种解决方案。就我而言,我不能真正使用单例,因为我有一个要继承的外部类,而我无法控制这个(库)。

基本上,我有许多继承自“TableRow”(库中的类)的类,我需要这些类中的每一个来实现某个静态方法(例如:GetStaticIdentifier)。最终,我需要将这些对象存储在它们的一种基本类型中,并在这个特定类型上使用静态方法。

我的问题,除了使用单例之外,还有其他解决方案吗? C# 中是否有我不知道的功能可以帮助我解决这个问题?

【问题讨论】:

  • “我需要这些类中的每一个来实现某个静态方法” 为什么?用例是什么?类不应该对自己的实现细节负责吗?
  • 为什么不能只调用单个静态方法?或者您需要每个类型具有给定名称的唯一静态方法?
  • 是的@AlexeiLevenkov,我需要对每个类有不同的实现,该方法返回一个基类型的对象,但它应该是实现静态方法的类型...跨度>
  • 如果你有这个类的对象为什么你需要静态方法,为什么不直接声明非静态虚拟方法并在子类中覆盖它们?

标签: c# inheritance interface static


【解决方案1】:

您似乎想提供一些元信息以及TableRow 的子类; 无需实例化特定子类即可检索的元信息

虽然 .NET 缺乏静态接口和静态多态性,但可以(在某种程度上,见下文)通过 custom attributes 解决这个问题。换句话说,您可以定义一个自定义属性类来存储您想要与您的类型相关联的信息:

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
public class StaticIdentifierAttribute : Attribute
{
    public StaticIdentifierAttribute(int id)
    {
        this.staticIdentifier = id;
    }

    private readonly int staticIdentifier;

    public int StaticIdentifier {
        get {
            return staticIdentifier;
        }
    }
}

然后您可以将此自定义属性应用于您的 TableRow 子类:

[StaticIdentifier(42)]
public class MyTableRow : TableRow
{
    // ...
}

然后您可以检索MyTableRow(或TableRow 的任何其他子类)的Type 实例,并使用GetCustomAttributes method 检索该类的StaticIdentifierAttribute instance and read out the value stored in itsStaticIdentifier` 属性。

与静态接口和静态多态性相比,缺点是编译时不能确保每个TableRow子类实际上都具有该属性;您必须在运行时捕获它(并且要么抛出异常,要么忽略相应的 TableRow 子类)。

此外,您不能确保该属性应用于TableRow 子类,但是,虽然这可能有点不整洁,但这并不重要(如果它应用于另一个类,它不会在那里产生任何影响,因为没有代码会为其他类处理它)。

【讨论】:

    【解决方案2】:

    如果您绞尽脑汁,您可以获得少量的编译器检查。但是,为您想要的每个标识符实例声明一个新的结构类型无疑是疯狂的。

    public interface IIdentifier
    {
        int Id { get; }
    }
    
    public class BaseClass { }
    
    public class ClassWithId<T> : BaseClass where T :  IIdentifier, new()
    {
        public static int Id { get { return (new T()).Id; } }
    }
    
    public struct StaticId1 : IIdentifier
    {
        public int Id { get { return 1; } }
    }
    
    public struct StaticId2 : IIdentifier
    {
        public int Id { get { return 2; } }
    }
    
    //Testing
    Console.WriteLine(ClassWithId<StaticId1>.Id);   //outputs 1
    Console.WriteLine(ClassWithId<StaticId2>.Id);   //outputs 2
    

    【讨论】:

      【解决方案3】:

      如何使用带有通用(或非)扩展方法的静态类?

      public static class Helper
      {
        fields...
      
        public static void DoSomething<T>(this T obj)
        {
           do something...
        }
      }
      

      【讨论】:

        猜你喜欢
        • 2014-02-15
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 2013-04-12
        • 1970-01-01
        • 2023-03-07
        • 2012-02-28
        • 2012-10-05
        相关资源
        最近更新 更多