0

我有一个泛型类,我将它的类型作为参数类型,例如int对于我的类中的方法,如下所示:

public class UnlimitedGenericArray<T>
{
 private void InsertItem(T item)
 {
  this.array[0] = item;
 }
}

现在,例如,当我想InsertItem()从控制台应用程序调用时,如何在运行时知道参数的类型?

    static void Main(string[] args)
    {
        UnlimitedGenericArray<int> oArray = new UnlimitedGenericArray<int>();
        while(true)
        {
         var userInput = Console.Readline();
         oArray.InsertItem(userInput);
        }
    }

我可以改为编写InsertItem(object item),然后按如下方法进行转换:

private void InsertItem(object item)
     {
      this.array[0] = (T)Convert.ChangeType(item, typeof(T));
     }

但这可能不是一个好习惯。我还需要知道客户端参数的类型,以便我可以在那里解析然后调用该方法。我是泛型的新手,所以请在这里帮助我。

4

3 回答 3

10

知道方法主体中的类型。如果您知道类型,那么您一开始就不会使用泛型。

您可能不想在这里使用泛型。如果您需要根据类型做出决定,那么您的方法不是通用的。

于 2013-07-30T21:23:37.917 回答
0

当您将泛型参数指定为 int 时,您不妨稍后假定该类型。因此,您在控制台应用程序中的代码变为:

static void Main(string[] args)
{
    // Specifying int here ...
    UnlimitedGenericArray<int> oArray = new UnlimitedGenericArray<int>(); 
    while(true)
    {
     string userInput = Console.ReadLine();
     int number = int.Parse(userInput);
     // ... therefore we know that the method below requires an int
     oArray.InsertItem(number);
    }
}
于 2013-07-30T22:33:23.870 回答
0

想到的唯一选择是为类提供一种从已知类型转换为 Type/Func 字典形式的方法,如下所示:

public class UnlimitedGenericArray<T>
{
    public IList<T> List { get; set; }

    private IDictionary<Type,Func<object,T>> InserterFuncDict{get;set;}

    public UnlimitedGenericArray(IDictionary<Type,Func<object,T>> inserterDict)
    {
        this.List = new List<T>();

        this.InserterFuncDict = inserterDict;
    }

    public void AddItem(object item)
    {
        var itemType = item.GetType();
        if(itemType == typeof(T))
        {
            this.List.Add((T)item);
        }
        else if(this.InserterFuncDict.ContainsKey(itemType))
        {
            this.List.Add(this.InserterFuncDict[itemType](item));
        }
        else 
        {
            var msg = "I don't know how to convert the value: {0} of type {1} into type {2}!";
            var formatted = string.Format(msg,item,itemType,typeof(T));
            throw new NotSupportedException(formatted);
        }
    }

}

然后用法如下所示:

var arr = new UnlimitedGenericArray<int>(new Dictionary<Type,Func<object,int>>()
{
    { typeof(string), v => int.Parse(v.ToString()) }
});

// ok! int == T
arr.AddItem(123); 
// ok, a mapping is provided
arr.AddItem("123"); 
// Error! 
//"I don't know how to convert the value: False of type System.Boolean into type System.Int32!"
arr.AddItem(false);

然后,如果说,您想添加布尔支持,您可以将声明更改为:

var arr = new UnlimitedGenericArray<int>(new Dictionary<Type,Func<object,int>>()
{
    { typeof(string), v => int.Parse(v.ToString()) }
    { typeof(bool), v => bool.Parse(v.ToString()) }
});

只需根据需要继续添加到类型转换字典即可。

于 2013-07-31T13:40:47.460 回答