当我只有一个泛型参数时,有没有办法在类型上调用静态成员。例如,如果我有这样的东西
public Get<T>(int id)
{
// I would like to do this
string s = T.SomeMethodName();
}
我可以这样做,但有点“讨厌”,然后无论是静态还是无关紧要。或者我可以使用Yuriy建议的反射。
ISomeKnownInterface i = (ISomeKnownInterface ) new T();
string s = i.SomeMethodName();
现在问题是哪种方法更好,创建使用反射的新实例
public TFormDto Get<TFormDto>(int entityId) where TFormDto : AbstractEntityFormDto, new()
{
// create new instance
AbstractEntityFormDto a = (AbstractEntityFormDto) new TFormDto();
string entityName = a.GetEntityFullTypeName();
// use reflection
Type type = typeof(TFormDto);
string entityName = type.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(m => m.Name == "GetEntityFullTypeName")
.Invoke(null, null);
答案 0 :(得分:1)
不会只是一直是AbstractBaseClass.GetFullName()。否则,您必须在T上使用反射来获取另一个类的静态方法。 This可能会有所帮助。
以下是一个简单的例子:
class TestClass
{
public static void Hello()
{
Console.WriteLine("World!!!");
}
}
public static void Test<T>() where T : class
{
Type type = typeof(T);
type.GetMethods(BindingFlags.Public | BindingFlags.Static)
.Single(m => m.Name == "Hello")
.Invoke(null, null);
}
使用您的示例,我假设您知道接口没有静态方法。我假设你的意思是你有一个接口,它有静态方法的签名,实现所述接口的类只是从实现中调用静态方法。这也可以,但是你不能保证调用正确的静态并确保T对该接口有约束,而不仅仅是new()。
答案 1 :(得分:1)
问题是不能保证T
具有名为SomeMethodName
的静态成员方法。如果您打算致电AbstractBaseClass.SomeMethodName
,请执行此操作。为什么这是不可能的理由是static interface methods讨论的延伸。
答案 2 :(得分:0)
如果不使用反射,就无法做到这一点。要调用静态方法,您始终需要指定实际类型。
如果要提高代码的编译时安全性,可以尝试避免反射。使方法非静态并将其放在接口中。这很可能(我不知道你的问题)是最干净的解决方案。
为了从接口和多态中受益,我做了很多非静态成员。有时我实现类似于单例模式的东西(例如,静态属性来获取实例),或者只是调用默认构造函数来获取实例并将其作为参数传递。
interface ISomeInterface
{
string SomeMethodName();
}
class SomeImplementation : ISomeInterface
{
public static Instance { get { return new SomeImplementation(); } }
public string SomeMethodName()
{
// implementation of SomeMethodName
}
}
public Get(ISomeInterface i)
{
string s = i.SomeMethodName();
}
public Example()
{
Get(SomeImplementation.Instance);
}
您也可以在泛型方法中创建新实例,也可以指定需要默认构造函数:
public Get<T>() where T : ISomeInterface, new()
{
T instance = new T();
string s = instance.SomeMethodName();
}
public Example()
{
Get<SomeImplementation>();
}