如何获得通用参数的类型

时间:2018-08-03 04:55:52

标签: c# generics

我无法确定应用程序中通用参数的类型。情况类似于下面的代码。当我得到通用ICollection时,我需要计数。如果没有,我需要处理单个对象。

using System;
using System.Collections.Generic;

namespace ConsoleApp1
{
    class Cat
    {
        public int Id { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            Cat cat1 = new Cat { Id = 1 };
            Cat cat2 = new Cat { Id = 2 };
            ICollection<Cat> cats = new List<Cat>();
            cats.Add(cat1);
            cats.Add(cat2);
            TestMethod<ICollection<Cat>>(cats);
            TestMethod<Cat>(cat1);
        }
        public static void TestMethod<T>(T parameter)
        {
            //if parameter is <ICollection<Cat>>, get count of cats?
            //else if (T is Cat), get id of the cat?
        }
    }
}

我错误地提出了这个问题,可能是猫,狗,鼠标或其他任何东西。我不知道这是什么,我也不需要。我正在尝试下面的代码,并得到转换错误。

(((ICollection)参数).Count;

如果它是任何对象的ICollection,我只需要计数即可。

非常感谢您的回答。

7 个答案:

答案 0 :(得分:0)

答案 1 :(得分:0)

您可以使用模式匹配来检查类型,例如:

switch (parameter)
{
    case ICollection<Cat> collection:
        var count = collection.Count;
        // Do something
        break;

    case Cat cat:
        var id = cat.Id;
        // Do something
        break;

    default:
        throw new InvalidOperationException("No cats.");
}

但是,如果您只想知道T是什么,则可以使用typeof(T)来获取用于调用该方法的泛型类型的System.Type对象。

答案 2 :(得分:0)

您可以获取如下所示的参数(T)的类型,然后检查:

var type = parameter.GetType();
if(type == typeof(List<Cat>))
{
 // do something
}
else if(type == typeof(Cat))
{
 //do something
}

并且为您提供信息,如果出现以下情况,则为猫的运行时间类型:

ICollection<Cat> cats = new List<Cat>();

是类型:

List<Cat>

不是

ICollection<Cat>

如果要检查并验证编译时类型,则在检查时可能需要对运行时类型使用显式强制转换。

其他替代方法是简单地使用“ is”关键字进行类型检查,如下所示:

if(parameter is ICollection<Cat>)
{

}
else if(parameter is Cat)
{

}

希望这会对您有所帮助。

答案 3 :(得分:0)

        int result;
        if (parameter is ICollection<Cat>)
            result = (parameter as (ICollection<Cat>)).Count;
        else if (parameter is Cat)
            result = (parameter as Cat).Id;

答案 4 :(得分:0)

这不是您要使用泛型的情况,因为这不是泛型的目的。

您在这里有两个选择。

您可以使用以下两种方法:

public void TestMethod(Cat cat) {...}
public void TestMethod(ICollection<Cat> cats) {...}

或者,如果您确实需要这种通用方法,则可以使用object作为参数。

 public void TestMethod(object obj) 
 {
    Cat cat = obj as cat;
    if(cat != null)
    { 

        return;
    }
    ICollection<Cat> cats = obj as ICollection<Cat>;
    if(cats != null)
    {

    }
 }

但是即使那样,如果您使用反射,这也是一个好主意。

答案 5 :(得分:0)

尝试一下可能会帮助您

class Cat
{
    public int Id { get; set; }
}
class Program
{
    static void Main(string[] args)
    {
        Cat cat1 = new Cat { Id = 1 };
        Cat cat2 = new Cat { Id = 2 };
        ICollection<Cat> cats = new List<Cat>();
        cats.Add(cat1);
        cats.Add(cat2);
        TestMethod<ICollection<Cat>>(cats);

        TestMethod<Cat>(cat1);
    }
    public static void TestMethod<T>(T parameter)
    {
        if (typeof(T) == typeof(ICollection<Cat>))  //if (parameter is ICollection<Cat>)
        {
            ICollection<Cat> cats = parameter as ICollection<Cat>;

            //Count your cats in count variable
            int count = cats.Count;
        }
        else
        if (typeof(T) == typeof(Cat))  // if (parameter is Cat)
        {
            Cat cat = parameter as Cat;

            //Get id of your cat in id variable
            int id = cat.Id;
        }
    }
}

答案 6 :(得分:0)

您的TestMethod可以如下编写...

public static void TestMethod<T>(T parameter)
{
    // Check if it is a ICollection of any object
    if (parameter is ICollection && parameter.GetType().IsGenericType)
    {
        var itemCount = ((ICollection)parameter).Count;
    }
    else
    {
        // write your else logic
    }
}