静态接口等同于c#

本文关键字:等同于 接口 静态 | 更新日期: 2023-09-27 17:54:52

我过去曾使用过单例,我知道这是一些试图解决静态接口问题的人的解决方案。在我的例子中,我不能真正使用单例,因为我继承了一个外部类,而我无法控制这个类(库)。

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

我的问题,是否有另一个解决方案,而不是使用单例?c#中是否有我不知道的功能可以帮助我解决这个问题?

静态接口等同于c#

似乎你想提供一些元信息以及TableRow的子类;可以在不实例化特定子类的情况下检索的元信息。

虽然。net缺乏静态接口和静态多态性,但这可以(在某种程度上,见下文)通过自定义属性来解决。换句话说,您可以定义一个自定义属性类来存储您想要与类型关联的信息:
[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
{
    // ...
}

您可以检索MyTableRowType实例(或TableRow的任何其他子类),并使用GetCustomAttributes方法检索该类的StaticIdentifierAttribute instance and read out the value stored in its StaticIdentifier '属性。

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

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

如果你纠结,你可以得到少量的编译器检查。然而,为每个标识符实例声明一个新的结构类型无疑是疯狂的。

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

如何使用静态类与泛型(或非)扩展方法?

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