简体   繁体   English

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

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

I have a generic class.我有一个通用的 class。 And this generic class needs to have another instance of the same class as one of its member.而这个通用的 class 需要有另一个相同的 class 实例作为其成员之一。

Basically, I'm trying to achieve a sequence of operations.基本上,我正在尝试实现一系列操作。 So every class will have to know the next item to continue the operation.所以每个 class 都必须知道下一项才能继续操作。

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

This is what I have tried so far.这是我到目前为止所尝试的。

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

But I cannot use it like this, since R in line no #3 is not defined yet.但我不能这样使用它,因为第 3 行中的R尚未定义。

在此处输入图像描述

It's actually impossible because not supported by the compiler else it would cause a stack overflow of the compiler with such thing that is endless and so impossible, because of the generic type verification as currently defined by the .NET specifications that are more strict than templates in C++.这实际上是不可能的,因为编译器不支持,否则它会导致编译器的堆栈溢出,这种事情是无穷无尽的,所以不可能,因为目前由 .NET 规范定义的泛型类型验证比 C++ 中的模板更严格.

You could use a LinkedList<ChainedItem<>> but the diamond operator hence true generic polymorphism are not available in C#:您可以使用LinkedList<ChainedItem<>>但菱形运算符因此在 C# 中不可用真正的通用多态性:

How to do generic polymorphism on open types in C#? 如何对 C# 中的开放类型进行泛型多态性?

Therefore perhaps you can write such thing using an interface and type checking, excluding null values:因此,也许您可以使用接口和类型检查来编写这样的东西,不包括 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);
  }
}

You will need to do something like this:您将需要执行以下操作:

Code fiddle代码小提琴

    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