静态接口等效 C#
Static interface equivalent C#
我过去曾使用过单例,我知道这是对一些试图解决静态接口问题的人的解决方案。在我的例子中,我不能真正使用单例,因为我有一个外部 class 是我继承的,我无法控制这个(库)。
基本上,我有许多 classes 继承自 "TableRow"(库中的 class),我需要这些 classes 中的每一个来实现一个某些静态方法(例如:GetStaticIdentifier)。最终,我需要将这些对象存储在它们的一种基本类型中,并对这个特定类型使用静态方法。
我的问题是,除了使用单例之外,还有其他解决方案吗? C# 中是否有我不知道的功能可以帮助我解决这个问题?
您似乎想提供一些元信息以及 TableRow
的子class;无需实例化特定子class.
即可检索的元信息
虽然 .NET 缺少静态接口和静态多态性,但这可以(在某种程度上,见下文)用 custom attributes 解决。换句话说,您可以定义一个自定义属性 class 来存储您想要与您的类型相关联的信息:
[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
subclasses:
[StaticIdentifier(42)]
public class MyTableRow : TableRow
{
// ...
}
然后您可以检索 Type
instance for MyTableRow
(or any other subclass of TableRow
) and use the GetCustomAttributes
method 以检索 StaticIdentifierAttribute instance and read out the value stored in its
StaticIdentifier` 属性 class。
与静态接口和静态多态性相比,缺点 是编译时无法确保每个 TableRow
subclass 实际上具有该属性;您将必须在运行时捕获它(并抛出异常,或忽略相应的 TableRow
subclass)。
此外,您无法确保该属性 仅 应用于 TableRow
子 class,但是,虽然这可能有点不整洁,这并不重要(如果它应用于另一个 class,它不会在那里产生任何影响,因为没有代码为其他 classes 处理过它)。
如果你绞尽脑汁,你可以获得少量的编译器检查。但是,为您想要的每个标识符实例声明一个新的结构类型无疑是疯狂的。
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
将静态 class 与通用(或非通用)扩展方法一起使用怎么样?
public static class Helper
{
fields...
public static void DoSomething<T>(this T obj)
{
do something...
}
}
我过去曾使用过单例,我知道这是对一些试图解决静态接口问题的人的解决方案。在我的例子中,我不能真正使用单例,因为我有一个外部 class 是我继承的,我无法控制这个(库)。
基本上,我有许多 classes 继承自 "TableRow"(库中的 class),我需要这些 classes 中的每一个来实现一个某些静态方法(例如:GetStaticIdentifier)。最终,我需要将这些对象存储在它们的一种基本类型中,并对这个特定类型使用静态方法。
我的问题是,除了使用单例之外,还有其他解决方案吗? C# 中是否有我不知道的功能可以帮助我解决这个问题?
您似乎想提供一些元信息以及 TableRow
的子class;无需实例化特定子class.
虽然 .NET 缺少静态接口和静态多态性,但这可以(在某种程度上,见下文)用 custom attributes 解决。换句话说,您可以定义一个自定义属性 class 来存储您想要与您的类型相关联的信息:
[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
subclasses:
[StaticIdentifier(42)]
public class MyTableRow : TableRow
{
// ...
}
然后您可以检索 Type
instance for MyTableRow
(or any other subclass of TableRow
) and use the GetCustomAttributes
method 以检索 StaticIdentifierAttribute instance and read out the value stored in its
StaticIdentifier` 属性 class。
与静态接口和静态多态性相比,缺点 是编译时无法确保每个 TableRow
subclass 实际上具有该属性;您将必须在运行时捕获它(并抛出异常,或忽略相应的 TableRow
subclass)。
此外,您无法确保该属性 仅 应用于 TableRow
子 class,但是,虽然这可能有点不整洁,这并不重要(如果它应用于另一个 class,它不会在那里产生任何影响,因为没有代码为其他 classes 处理过它)。
如果你绞尽脑汁,你可以获得少量的编译器检查。但是,为您想要的每个标识符实例声明一个新的结构类型无疑是疯狂的。
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
将静态 class 与通用(或非通用)扩展方法一起使用怎么样?
public static class Helper
{
fields...
public static void DoSomething<T>(this T obj)
{
do something...
}
}