繁体   English   中英

如何在 ZD7EFA19FBE7D3972FD5ADB6024223D74 中的通用 class 中使用通用 class 的 object?

[英]How to use an object of a generic class inside a generic class in C#?

我有一个通用的 class。 而这个通用的 class 需要有另一个相同的 class 实例作为其成员之一。

基本上,我正在尝试实现一系列操作。 所以每个 class 都必须知道下一项才能继续操作。

ChainedItem(Uri) -> ChainedItem(String) -> ChainedItem(MyClass) ->....

这是我到目前为止所尝试的。

public abstract class ChainedItem<T>
{        
    private ChainedItem<R> m_chainedItem;

    public void SetNextChainedItem(ChainedItem<R> chainedItem)
    {
        m_chainedItem = chainedItem;
    }

    public abstract void DoOperation(T data);

    public virtual void ContinueNextOperation<R>(R data)
    {
        if(m_chainedItem != null)
            m_chainedItem.DoOperation(data);
    }
}

但我不能这样使用它,因为第 3 行中的R尚未定义。

在此处输入图像描述

这实际上是不可能的,因为编译器不支持,否则它会导致编译器的堆栈溢出,这种事情是无穷无尽的,所以不可能,因为目前由 .NET 规范定义的泛型类型验证比 C++ 中的模板更严格.

您可以使用LinkedList<ChainedItem<>>但菱形运算符因此在 C# 中不可用真正的通用多态性:

如何对 C# 中的开放类型进行泛型多态性?

因此,也许您可以使用接口和类型检查来编写这样的东西,不包括 null 值:

public interface IChainedItem
{
  void DoOperation(object value);
}
public abstract class ChainedItem<T> : IChainedItem
{
  private IChainedItem m_chainedItem;

  public void SetNextChainedItem(IChainedItem chainedItem)
  {
    m_chainedItem = chainedItem;
  }

  public abstract void DoOperation(T data);

  public virtual void ContinueNextOperation(object data)
  {
    if ( m_chainedItem != null )
      m_chainedItem.DoOperation(data);
  }

  public void DoOperation(object value)
  {
    if ( value == null )
      throw new ArgumentNullException();
    var typeIn = value.GetType();
    var typeRequired = typeof(T);
    if ( typeIn != typeRequired )
    {
      string message = $"Bad type in ChainedItem.DoOperation(object): "
                     + $"{typeRequired.Name} is required and not {typeIn.Name}.";
      throw new ArgumentException(message);
    }
    DoOperation((T)value);
  }
}

您将需要执行以下操作:

代码小提琴

    public class Program
    {
       public static void Main()
       {
         var testObj1 = new ChainedItem<int, string>();
         var testObj2 = testObj1.GetNextChainedItem<bool>();
        
         Console.WriteLine(testObj1.GetType().ToString());
         Console.WriteLine(testObj2.GetType().ToString());
        
       }
   }



   public class ChainedItem<T,R>
{        
    private object NextChainedItem;
    
    public ChainedItem<R,S> GetNextChainedItem<S>()
    {
        ChainedItem<R,S>NextChainedItem = new ChainedItem<R,S>();
        return NextChainedItem;
    }
    
    
   
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM