【问题标题】:C# Interface Type Casting using Base class使用基类的 C# 接口类型转换
【发布时间】:2019-06-25 21:57:58
【问题描述】:

您好,我想知道是否可以通过以下方式在接口中转换类型及其具体实现。

 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)

【问题讨论】:

  • 您需要ProcessBassTypeClass 来实现IProcessBaseType&lt;T&gt; 的所有三个变体,例如IProcessBaseType&lt;BaseTypeV1&gt;IProcessBaseType&lt;BaseTypeV2&gt;IProcessBaseType&lt;BaseTypeV3&gt;

标签: c# .net class .net-core typecasting-operator


【解决方案1】:

就这么简单:

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();
        }
    }
}

【讨论】:

  • 感谢您的回复!我想我实际上会使用您提供的第一个示例,因为对于 BaseType 类的每个版本我都有不同的工作要做:)
  • @user2662520 - 是的,但在第二个示例中,您仍然可以为 BaseType 的每个版本完成不同的工作。您可以创建一个Dictionary&lt;Type, Delegate&gt; 以便能够存储和检索特定于类型的代码。这允许您在运行时构建处理。
【解决方案2】:

没有IProcessBaseType这样的接口,它与IProcessBaseType&lt;T&gt;是不同的类型。

如果你把它添加为通用接口,你可以做一个解决方案:

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

Example on DotNetFiddle

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    相关资源
    最近更新 更多