Приведение типов интерфейса C # с использованием базового класса - PullRequest
1 голос
/ 26 июня 2019

Привет, мне интересно, можно ли привести тип в Интерфейс и его конкретную реализацию следующим образом.

 public class BaseTypeClass

 public class BaseTypeV1 : BaseTypeClass

 public class BaseTypeV2 : BaseTypeClass

 public class BaseTypeV3 : BaseTypeClass



 public interface IProcessBaseType<T> where T : BaseTypeClass

      void Process(T baseType)



 public class ProcessBassTypeClass : IProcessBassType

      void Process(BaseTypeV1 data)

      void Process(BaseTypeV2 data)

      void Process(BaseTypeV3 data)

Ответы [ 2 ]

1 голос
/ 26 июня 2019

Это так же просто, как сделать это:

public class ProcessBassTypeClass : IProcessBaseType<BaseTypeV1>, IProcessBaseType<BaseTypeV2>, IProcessBaseType<BaseTypeV3>
{
    public void Process(BaseTypeV1 baseType)
    {
        throw new NotImplementedException();
    }

    public void Process(BaseTypeV2 baseType)
    {
        throw new NotImplementedException();
    }

    public void Process(BaseTypeV3 baseType)
    {
        throw new NotImplementedException();
    }
}

Альтернатива, которую вы можете рассмотреть, заключается в следующем:

public interface IProcessBaseType
{
    void Process<T>(T baseType) where T : BaseTypeClass;
}

public class ProcessBassTypeClass : IProcessBaseType
{
    public void Process<T>(T baseType) where T : BaseTypeClass
    {
        throw new NotImplementedException();
    }
}

Это позволяет использовать любой объект типа BaseTypeClassи позволяет Process вызвать typeof(T), чтобы получить фактический тип во время выполнения.Полезно, если вы хотите динамически создать список доступных процессоров.


Вот простой пример того, как вы можете добавлять процессоры, специфичные для типа, во время выполнения при использовании второго примера кода:

public class ProcessBassTypeClass : IProcessBaseType
{
    private Dictionary<Type, Delegate> _processors = new Dictionary<Type, Delegate>();

    public void AttachProcessor<T>(Action<T> processor) where T : BaseTypeClass
    {
        _processors[typeof(T)] = processor;
    }

    public void Process<T>(T baseType) where T : BaseTypeClass
    {
        if (_processors.ContainsKey(typeof(T)))
        {
            ((Action<T>)(_processors[typeof(T)])).Invoke(baseType);
        }
        else
        {
            throw new NotSupportedException();
        }
    }
}
0 голосов
/ 26 июня 2019

Нет такого интерфейса, как IProcessBaseType, который отличается от IProcessBaseType<T>.

Если вы добавите его в качестве общего интерфейса, вы можете принять решение:

public interface IProcessBaseType
{
    void Process(BaseTypeClass baseType);
}

public interface IProcessBaseType<T> : IProcessBaseType where T : BaseTypeClass
{
      void Process(T baseType);
}

Теперь вы можете сделать это:

public class ProcessBassTypeClass : IProcessBaseType
{
    public void Process(BaseTypeClass data)
    {
        Console.WriteLine("Processing as BaseTypeClass");
    }
    public void Process<T>(T data)
    {
        Console.WriteLine("Processing as generic with T = {0}", typeof(T).Name);
    }
}

Тестовая программа:

public class MyProgram 
{ 
    static public void Main(string[] args) 
    {
        var processor = new ProcessBassTypeClass();

        processor.Process( new BaseTypeClass() );
        processor.Process( new BaseTypeV1() );
        processor.Process( new BaseTypeV2() );
        processor.Process( new BaseTypeV3() );
    } 
} 

Выход:

Processing as BaseTypeClass
Processing as generic with T = BaseTypeV1
Processing as generic with T = BaseTypeV2
Processing as generic with T = BaseTypeV3

Пример для DotNetFiddle

...