返回从泛型方法泛型列表

问题描述 投票:0回答:3

我需要从如下代码泛型列表如下返回一个泛型列表qazxsw POI:

templateFields

我得到以下错误,回程:

对象必须实现Iconvertible。

我明白qazxsw POI未实现IConvertible使用一changeType。什么是返回qazxsw POI的最佳途径

c# generics
3个回答
1
投票

添加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));

0
投票

我觉得这里的问题是,当你这样做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

0
投票

你宣布一个接口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>
© www.soinside.com 2019 - 2024. All rights reserved.