[英]Access abstract static interface member
如何从接口IFoo
或实例 object 从FooImpl
获取已实现的Name
?
public interface IFoo {
static abstract string Name { get; }
}
public class FooImpl : IFoo {
public static string Name => "Foo";
}
我似乎无法从这些方法中获取Name
值。 我错过了什么吗? 请注意,我想在不知道正在使用的实现的情况下从IFoo
的任何实现访问Name
。 因此, FooImpl.Name
将编译并运行,但这不是我想要直接执行的操作。
IFoo anImpl = new FooImpl();
Console.WriteLine(anImpl.Name); // [CS0176] Member 'IFoo.Name' cannot be accessed with an instance reference; qualify it with a type name instead
// I know this won't work
Console.WriteLine(IFoo.Name); // [CS8926] A static virtual or abstract interface member can be accessed only on a type parameter.
static string GetName<T>() where T : IFoo
{
return T.Name;
}
// I know this won't work
Console.WriteLine(GetName<IFoo>()); // [CS8920] The interface 'IFoo' cannot be used as type argument. Static member 'IFoo.Name.get' does not have a most specific implementation in the interface.
static string GetName2<T>(T implementation) where T : IFoo
{
return T.Name;
}
Console.WriteLine(GetName2(anImpl)); // [CS8920] The interface 'IFoo' cannot be used as type argument. Static member 'IFoo.Name.get' does not have a most specific implementation in the interface.
我不确定还能尝试什么。 这篇文章是相关的,但除了反思之外我没有看到答案。
请注意,我想在不知道正在使用的实现的情况下从
IFoo
的任何实现访问Name
是的,这是不可能的(除了反思)。 Static 抽象接口成员与任何其他 static 成员一样属于类型,而不属于实例,因此只能通过类型检索它们。 您可以使用链接答案中的解决方案或“动态”调用GetName
,即:
var fooName = typeof(...).GetMethod(nameof(....GetName))
.MakeGenericMethod(anImpl.GetType())
.Invoke(null, null);
您还可以将任何一种方法包装在一些帮助器中,并将处理后的类型值存储到Dictionary<Type, string>
(或ConcurrentDictionary
)中以减轻反射成本。 甚至预先构建字典(取决于用例)。
还有另一种方法,但它需要对类型层次结构进行一些更改。 您可以使用奇怪的重复模板模式(CRTP) + 额外方法 + 带有默认方法实现的额外通用接口:
public interface IFoo {
static abstract string Name { get; }
public string GetName();
}
public interface IFoo<T> : IFoo where T : IFoo<T> // CRTP
{
string IFoo.GetName() => T.Name;
}
public class FooImpl : IFoo<FooImpl> {
public static string Name => "Foo";
}
和用法:
IFoo anImpl = new FooImpl();
Console.WriteLine(anImpl.GetName());
您使用只读属性实现它并为其分配默认值。
public interface IFoo {
static abstract string Name { get; }
}
public class FooImpl : IFoo {
public static string Name {get; } = "Foo";
}
然后你读取消费的价值
public void DoStuff<T>() where T : IFoo
{
string name = T.Name;
}
或具体实现
public void DoStuff()
{
string name = FooImpl.Name;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.