Подтвердить что ты не робот

Вызов статического метода интерфейса С# с дженериками

Есть ли простой способ реализовать это и, если возможно, не инициировать объект:

interface I
{
     static  string GetClassName();
}

public class Helper
{

    static void PrintClassName<T>() where T : I
    {
         Console.WriteLine(T.GetClassName());
    }
}
4b9b3361

Ответ 1

Попробуйте вместо этого использовать метод расширения:

public interface IMyInterface
{
     string GetClassName();
}

public static class IMyInterfaceExtensions
{
    public static void PrintClassName<T>( this T input ) 
        where T : IMyInterface
    {
         Console.WriteLine(input.GetClassName());
    }
}

Это позволяет добавить статический метод расширения/утилиты, но вам все равно нужен экземпляр вашей реализации IMyInterface.

У вас не может быть интерфейсов для статических методов, потому что это не имеет смысла, они являются методами утилиты без экземпляра и, следовательно, у них действительно нет типа.

Ответ 2

Вы не можете наследовать статические методы. Из-за этого ваш код не будет компилироваться, потому что из-за этого у интерфейса не может быть статических методов.

Как указано из littleguru:

Наследование в .NET работает только на база экземпляров. Статические методы определяется на уровне типа не на уровень экземпляра. Вот почему переопределение не работает со статическими методы/свойства/события...

Статические методы удерживаются только один раз в Память. Нет виртуальной таблицы и т.д. созданный для них.

Если вы вызываете метод экземпляра в .NET, вы всегда даете пример. Это скрыто .NET. но это происходит. Каждый экземпляр метод имеет в качестве первого аргумента указатель (ссылку) на объект, метод запускается. Это не происходит со статическими методами (поскольку они определенные на уровне типа). Как следует компилятор решил выбрать метод для вызова?

Ответ 4

Если вы только после имени типа, вы можете просто сделать это:

public class Helper
{
    static void PrintClassName<T>()
    {
         Console.WriteLine(typeof(T).Name);
    }
}

Ответ 5

Объявление static property, event или method в определении интерфейса не считается юридическим определением. Это связано с тем, что интерфейсы считаются контрактами и как таковые представляют собой то, что будет реализовано каждым клиентским экземпляром этого интерфейса.

В объявлении A static говорится, что член static не требует реализации физического клиента для выполнения требуемых функций, и это не соответствует общей концепции интерфейсов: предоставление проверенного контракта.

Ответ 6

Ответ - это квалифицированный "не совсем, а Сортировка". Вы можете предоставить статический метод расширения всем разработчикам данного интерфейса и затем вызывать это от своего исполнителя в свойстве или другом методе. В качестве примера:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace InterfacesWithGenerics
{
    class Program
    {
        static void Main(string[] args)
        {
            Helper.PrintClassName<Example>(new Example());
            Console.ReadLine();
        }
    }

    public class Example : I
    {
        #region I Members

        public string ClassName
        {
            get { return this.GetClassName(); }
        }

        #endregion
    }

    public interface I
    {
        string ClassName { get; }
    }

    public class Helper
    {

        public static void PrintClassName<T>(T input) where T : I
        {           
            Console.WriteLine( input.GetClassName()) ;
        }
    }

    public static class IExtensions
    {
        public static string GetClassName(this I yourInterface)
        {
            return yourInterface.GetType().ToString();
        }
    }
}

Здесь у нас есть интерфейс (I), который определяет интересующее нас свойство и статический метод расширения (GetClassName), который применяется ко всем членам его типа, который выполняет работу по поиску нужной нам информации. У нас есть класс (пример), который реализует интерфейс I, поэтому, когда мы вызываем наш статический вспомогательный класс, проходящий в экземпляре примера, он запускает против него статический метод. К сожалению, неверно ссылаться на тип T непосредственно внутри самого метода как переменной, вам нужно будет передать экземпляр в приложение.

Ответ 7

Вы можете определить className как атрибут для определенного класса. Это предпочтительнее хранить метаданные в .net. Таким образом, вы можете запросить атрибут для данного класса, и вам не нужен экземпляр.