我需要从如下代码泛型列表如下返回一个泛型列表qazxsw POI:
templateFields
我得到以下错误,回程:
对象必须实现Iconvertible。
我明白qazxsw POI未实现IConvertible使用一changeType。什么是返回qazxsw POI的最佳途径
添加qazxsw POI制约qazxsw POI和使用下面的代码
public interface TestData
{
string field { get; set; }
string fieldName { get; set; }
string type { get; set; }
}
private static IList<T> GETCG<T>(string test, string type) where T : Program.TestData
{
XmlNodeList extractNode = xdoc.SelectNodes(
@".//mediaInstances/mediaInstance/properties/templateFields/templateField", manager);
var nodees = new List<XmlNode>(extractNode.Cast<XmlNode>());
var templateFields = nodees.Cast<XmlNode>().Select(x => new
{
field = (String)x.Attributes["userName"].Value,
fieldName = (String)x.Attributes["name"].Value
.Substring(0, x.Attributes["name"].Value.IndexOf(':')),
type = (String)x.Attributes["name"].Value.Substring(x.Attributes["name"].Value
.IndexOf(':') + 1, 4)
}).ToList();
}
return (T)Convert.ChangeType(templateFields, typeof(T));
我觉得这里的问题是,当你这样做templateFields
您要选择匿名类型,然后templateFields
失败,因为匿名类型仅包括new()
特性,并没有实现T
。取而代之的是,我们要选择一个新的private static IList<T> GETCG<T>(string test, string type) where T : TestData, new()
{
XmlNodeList extractNode = xdoc.SelectNodes(@".//mediaInstances/mediaInstance/properties/templateFields/templateField", manager);
var nodees = new List<XmlNode>(extractNode.Cast<XmlNode>());
var templateFields = nodees.Cast<XmlNode>().Select(x => new T() //not anonymous type but T object
{
field = x.Attributes["userName"].Value,
fieldName = (string)x.Attributes["name"].Value.Substring(0, x.Attributes["name"].Value.IndexOf(':')),
type = x.Attributes["name"].Value.Substring(x.Attributes["name"].Value.IndexOf(':') + 1, 4)
}).ToList();
return templateFields;
}
。但是,为了做到这一点,我们也必须包括对select new { ... }
一个Convert.ChangeType
,这意味着public read-only
必须有一个默认的构造函数(这样我们就可以创建它的一个实例)。
通过这样做,我们不需要任何转换,因为我们有一个IConvertible
作为T
的结果。
您还可以通过在一行中选择new() constraint,而不是创建第二个变量,做的第一个的T
减少一些代码。
像这样的东西应该工作:
T
你宣布一个接口List<T>
但没有宣布任何类型的实现它。你不能施放任何类型恰好具有相同的属性偶然到该接口。你必须创建一个类或结构实现它。此外,与通常的.NET命名约定,接口名称以大写字母Select
和属性名开始有PascalCase。
有了这些声明...
IEnumerable<XmlNode>
你可以写
cast
注意,这个方法是不通用的。为了使private static IList<T> GETCG<T>(string test, string type) where T : TestData, new()
{
IEnumerable<XmlNode> templateFieldNodes = xdoc
.SelectNodes(".//mediaInstances/mediaInstance/properties/templateFields/templateField",
manager)
.Cast<XmlNode>();
return templateFieldNodes.Select(x => new T
{
field = (String)x.Attributes["userName"].Value,
fieldName = (String)x.Attributes["name"].Value
.Substring(0, x.Attributes["name"].Value.IndexOf(':')),
type = (String)x.Attributes["name"].Value.Substring(x.Attributes["name"].Value
.IndexOf(':') + 1, 4)
}).ToList();
}
创建TestData
,新的数据必须被浇铸成接口I
。
现在的问题是,你是否还需要接口,或者如果你喜欢直接使用类。
如果你仍然想的方法是通用的,你必须告诉它public interface ITestData
{
string Field { get; set; }
string FieldName { get; set; }
string Type { get; set; }
}
public class TestData : ITestData
{
public string Field { get; set; }
public string FieldName { get; set; }
public string Type { get; set; }
}
必须与private static IList<ITestData> GETCG(string test, string type)
{
XmlNodeList extractNode = xdoc.SelectNodes(
@".//mediaInstances/mediaInstance/properties/templateFields/templateField", manager);
var nodees = new List<XmlNode>(extractNode.Cast<XmlNode>());
var templateFields = nodees.Cast<XmlNode>().Select(x => (ITestData)new TestData {
Field = (String)x.Attributes["userName"].Value,
FieldName = (String)x.Attributes["name"].Value
.Substring(0, x.Attributes["name"].Value.IndexOf(':')),
Type = (String)x.Attributes["name"].Value.Substring(x.Attributes["name"].Value
.IndexOf(':') + 1, 4)
}).ToList();
return templateFields;
}
约束默认构造函数。你必须调用与具体类型的方法。即,你不能用接口调用它,因为这其中没有一个构造函数。
.ToList()
与调用
IList<ITestData>