【问题标题】:Call generic method c#调用泛型方法c#
【发布时间】:2016-02-12 13:44:57
【问题描述】:

如何调用泛型方法,我听说过反射,但我觉得我做错了,请检查。

 public static LinkedListNode<T> MergeSortLL<T>(LinkedListNode<T> Head) where T : IComparable<T>
    {

        if (Head == null || Head.Next == null)
        {
            return Head;
        }
        LinkedListNode<T> middle = GetMiddle<T>(Head);
        LinkedListNode<T> half = middle.Next;
        middle.Next = null;

        return Merge(Head, half);

    }

在这里我试图用参数调用我的泛型方法

    public void MSort()
    {
        Type type = typeof(MergeSort);
        MethodInfo method = typeof(MergeSort).GetMethod("MergeSortLL");
        MethodInfo generic = method.MakeGenericMethod(type);
        generic.Invoke(null, null);
    }

更新 2。 这里有更多信息我在我的班级 MergeSort 以及我为什么使用 IComparable

class MergeSort
{

    public static LinkedListNode<T> MergeSortLL<T>(LinkedListNode<T> Head) where T : IComparable<T>
    {

        if (Head == null || Head.Next == null)
        {
            return Head;
        }
        LinkedListNode<T> middle = GetMiddle<T>(Head);
        LinkedListNode<T> half = middle.Next;
        middle.Next = null;

        return Merge(Head, Head, half);

    }

    public static LinkedListNode<T> Merge<T>(LinkedListNode<T> Head, LinkedListNode<T> Left, LinkedListNode<T> Right) where T : IComparable<T>
    {

        LinkedListNode<T> mHead = Head;
        LinkedListNode<T> curr = mHead;

        while (Left != null && Right != null)
        {
            if (Left.Value.CompareTo(Right.Value) <= 0)
            {
                curr.Next = Left;
                Left = Left.Next;
            }
            else
            {
                curr.Next = Right;
                Right = Right.Next;
            }
            curr = curr.Next;
        }
        curr.Next = (Left == null) ? Right : Left;

        return mHead.Next;
    }

    public static LinkedListNode<T> GetMiddle<T>(LinkedListNode<T> Head) where T : IComparable<T>
    {
        if (Head == null)
        {
            return Head;
        }

        LinkedListNode<T> slow, fast;
        slow = fast = Head;
        while (fast.Next != null && fast.Next.Next != null)
        {
            slow = slow.Next; fast = fast.Next.Next;
        }
        return slow;
    }

}

【问题讨论】:

  • 可以看stackoverflow中的帖子stackoverflow.com/questions/3957817/…
  • 只需var result = MergeSort.MergeSorLL(HeadNodeOfLinkedList); 泛型将被推断
  • 泛型和反射不能很好地混合。如果你不知道类型,你就不能在编译时对 output 做任何事情。如果这样做,则无需使用反射,只需按照@juharr 的建议调用即可。

标签: c# generics reflection


【解决方案1】:

查看您要离开的 cmets 以及您遇到的问题。在我看来,你的意图是将 LinkedList 传递给这个方法,所以它应该是:

public static LinkedListNode<T> MergeSortLL<T>(LinkedList<T> Head) where T : IComparable<T>

那么你应该像这样被调用:

var head = new LinkedList<int>();

MergeSortLL<int>(head)

你看我已经将 int 设置为我希望方法被约束的类型。

但是,由于您将拥有一个强类型的 LinkedList,C# 编译器将在 MergeSortLL 方法上隐式设置 &lt;int&gt;,从而减少对以下的调用:

MergeSortLL(head);

您还对通用类型 T 施加了通用约束,确保您使用的任何类型都继承自 IComparable&lt;T&gt;,当大声说出来时听起来有点奇怪,但似乎是正确的。

【讨论】:

  • 我认为MergeSort是包含方法的类,不一定是泛型链表中保存的类型。
  • 阅读他调用该方法的方式,它会相信我认为我做了什么。但是,我更倾向于同意你的观点......这从 OP 中完全清楚。
  • 我基于typeof(MergeSort).GetMethod("MergeSortLL")
  • 是的,MergeSort 是类,我输入了MergeSort.MergeSortLL&lt;MergeSort&gt;(Head); 并有错误cannot convert from 'task.LinkedListNode&lt;T&gt;' to 'task.LinkedListNode&lt;task.MergeSort&gt;
  • @Vitaliy 你需要像这样MergeSort.MergeSortLL(list.First) 传递LinkedList 的头部。或者更改方法以使用LinkedList&lt;T&gt; 而不是LinkedListNode&lt;T&gt;
【解决方案2】:

如果你有一个LinkedList&lt;T&gt;,只需将它的头部(通过First 属性)传递给方法,类型就会被推断出来。

var list = new LinkedList<int>();
var head = list.First; 
var sorted = MergeSort.MergeSortLL(head);

假设MergeSort 是一个静态类,您可以通过在LinkedListNode&lt;T&gt; Head 参数前添加this 使其成为扩展方法,然后就可以像实例方法一样调用它。

var sorted = head.MergeSortLL();

【讨论】:

    猜你喜欢
    • 2011-04-23
    • 1970-01-01
    • 1970-01-01
    • 2011-05-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多