Ts там любой способ вызвать статический член по типу, когда у меня есть только общий параметр. Например, если у меня есть что-то вроде этого
public Get<T>(int id)
{
// I would like to do this
string s = T.SomeMethodName();
}
Я мог бы сделать это так, но это "yucky", и тогда неважно, статично оно или нет. Или я мог бы использовать отражение, предложенное Юрием.
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);
Разве это не всегда будет AbstractBaseClass.GetFullName(). В противном случае вы должны использовать отражение на T, чтобы получить статический метод другого класса. Это может быть полезно.
Ниже приведен простой пример:
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 имеет ограничение на этот интерфейс, а не только новый().
Проблема не в том, что T
имеет статический метод-член с именем SomeMethodName
. Если вы хотите позвонить AbstractBaseClass.SomeMethodName
, сделайте это. Обоснование того, почему это невозможно, - это расширение методов методов статического интерфейса.
Нет никакого способа сделать это без использования отражения. Чтобы вызвать статический метод, вам всегда нужно указать фактический тип.
Если вы хотите улучшить безопасность кода во время компиляции, вы попытаетесь избежать отражения. Сделайте метод нестатическим и поместите его в интерфейс. Это, скорее всего, (я не знаю, ваша проблема) будет самым чистым решением.
Я сделал немало членов, не статических, чтобы воспользоваться интерфейсами и полиморфизмом. Иногда я реализую нечто похожее на шаблон singleton (например, статическое свойство для получения экземпляра) или просто вызываю конструктор по умолчанию, чтобы получить экземпляр и передать его в качестве аргумента.
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>();
}