以下代码给出了错误:
Cannot implicitly convert type T to string.
Cannot implicitly convert type T to int.
当我调用它时,我该怎样做才能让这个方法返回我用T定义的变量类型?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGener234
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("his first name is {0}", GetPropertyValue<string>("firstName"));
Console.WriteLine("his age is {0}", GetPropertyValue<int>("age"));
}
public static T GetPropertyValue<T>(string propertyIdCode)
{
if (propertyIdCode == "firstName")
return "Jim";
if (propertyIdCode == "age")
return 32;
return null;
}
}
}
这是一个更完整的示例,说明为什么我需要通用解决方案,即我有一个类将值保存为字符串,无论类型如何,这个通用解决方案只是使调用代码更清晰:
using System;
using System.Collections.Generic;
namespace TestGener234
{
class Program
{
static void Main(string[] args)
{
List<Item> items = Item.GetItems();
foreach (var item in items)
{
string firstName = item.GetPropertyValue<string>("firstName");
int age = item.GetPropertyValue<int>("age");
Console.WriteLine("First name is {0} and age is {1}.", firstName, age);
}
Console.ReadLine();
}
}
public class Item
{
public string FirstName { get; set; }
public string Age { get; set; }
public static List<Item> GetItems()
{
List<Item> items = new List<Item>();
items.Add(new Item { FirstName = "Jim", Age = "34" });
items.Add(new Item { FirstName = "Angie", Age = "32" });
return items;
}
public T GetPropertyValue<T>(string propertyIdCode)
{
if (propertyIdCode == "firstName")
return (T)(object)FirstName;
if (propertyIdCode == "age")
return (T)(object)(Convert.ToInt32(Age));
return default(T);
}
}
}
答案 0 :(得分:13)
这很麻烦;为了使编译器满意,你可以进行双重转换,但这意味着值类型的框:
public static T GetPropertyValue<T>(string propertyIdCode)
{
if (propertyIdCode == "firstName")
return (T)(object)"Jim";
if (propertyIdCode == "age")
return (T)(object)32;
return default(T);
}
实际上,我认为使用object
返回类型可能会更好。
答案 1 :(得分:4)
这是滥用泛型。如果泛型类型参数可能有少量类型,那么只需用许多方法替换它:
string GetTextProperty(string propertyName) { ... }
int GetNumberProperty(string propertyName) { ... }
Giraffe GetGiraffeProperty(string propertyName) { ... }
答案 2 :(得分:2)
这应该有用......
public static T GetPropertyValue<T>(string propertyIdCode)
{
if (propertyIdCode == "firstName")
return (T)Convert.ChangeType("Jim", typeof(T));
if (propertyIdCode == "age")
return (T)Convert.ChangeType(22, typeof(T));
return default(T);
}
答案 3 :(得分:1)
GetPropertyValue<string>("age")
想要返回一个字符串。将其更改为GetPropertyValue<int>("age")
,只要“年龄”是您的参数值,它就会有效。
您的实现最好获取泛型参数T的类型,以便选择返回的内容而不是基于函数参数。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TestGener234
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("his first name is {0}", GetPropertyValue<string>("firstName"));
Console.WriteLine("his age is {0}", GetPropertyValue<int>("age"));
}
public static T GetPropertyValue<T>(string propertyIdCode)
{
if (typeof(T) == typeof(string) && propertyIdCode == "firstName")
return "Jim";
if (typeof(T) == typeof(string) && propertyIdCode == "age")
return "32";
if (typeof(T) == typeof(int) && propertyIdCode == "age")
return 32;
throw (new ArgumentException());
}
}
}
答案 4 :(得分:1)
您可以从GetPropertyValue返回对象然后进行强制转换。您正在尝试使用泛型方法根据输入参数返回特定类型。听起来令人困惑: - )
public static object GetPropertyValue(string propertyIdCode)
{
if (propertyIdCode == "firstName")
return "Jim";
if (propertyIdCode == "age")
return 32;
return null;
}
然后投射(int)GetPropertyValue("age");
答案 5 :(得分:1)
通常当您在通用方法内部进行转换时,这是一个设计问题。通常,您希望在方法中保留类型泛型(无强制转换,不基于类型进行拼写),如下所示:
public class Properties<T>
{
private Dictionary<string, T> _dict = new Dictionary<string, T>();
public void SetPropertyValue<T>(string propertyIdCode, T value)
{
_dict[propertyIdCode] = value;
}
public T GetPropertyValue<T>(string propertyIdCode)
{
return _dict[propertyIdCode];
}
}
另一方面,如果你想通过他们的名字访问对象的属性(看起来这就是你正在做的事情,对不起,如果我弄错了),正确的方法是使用反射({{3 }}):
public object GetPropertyValue(object obj, string propertyIdCode)
{
PropertyInfo pinfo = obj.GetType().GetProperty(propertyIdCode);
return pinfo.GetValue(obj, null);
}
答案 6 :(得分:0)
public static T GetPropertyValue<T>(string propertyIdCode)
{
object result = null;
if (propertyIdCode == "firstName")
result = "Jim";
if (propertyIdCode == "age")
result = 32;
return result == null ? default(T) : (T)result;
}
答案 7 :(得分:0)
Marc的双重演示示例是让编译器正常运行的正确方法。
您可以为每种值类型编写sperate方法,并为引用类型提供通用方法。这将停止对值类型的停止装箱。
这仅在被访问的对象没有用于存储的盒子时有用(例如,不存储为对象)。
public static T GetPropertyValue<T>(string propertyIdCode)
{
}
public static int GetPropertyInt(string propertyIdCode)
{
}
答案 8 :(得分:0)
还有另一种方法 - 使用Convert.ChangeType:
CType(Convert.ChangeType(mItem, GetType(TItem)), TItem)