0

我有许多存储在列表中的类。我正在尝试创建一个接受 List 作为泛型类型并将适当列表中每个元素的内容作为字符串返回的方法。

这是许多类之一的示例。这将被定义为 List<Player>:

public class Player
{
    public int PlayerId { get; set; }
    public string PlayerName { get; set; }
    public string FavoriteThing { get; set; }
}

我仍然在这里努力使语法正确:

  public static string GetStringOfData<T>(List<T> data)
    {
        string dataString = string.Empty;
        var type = data.GetType();

        // Insert magic here to get values for PlayerId, PlayerName, etc...

        return dataString;
    }

我们怎样才能做到这一点?我正在使用 C# 4.0。

更新 我使用的类是从 edmx 模型生成的,连接到数据库。这是一个报告工具,它将解析各种表格并通过电子邮件向用户报告错误。用户特别要求能够查看所有字段的内容。

4

5 回答 5

5

每种类型都继承ToStringobject. ToString在你的类中覆盖。

public class Player
{
    ...
    public override string ToString()
    {
        return String.Format("Player [ID = {0}, Name = {1}]",
                             PlayerId, PlayerName);
    }

}

然后你可以使用非泛型IEnumerable来处理它们。(为什么要限制自己List<T>是否可以与 共进午餐IEnumerable?后者将与List<T>、数组、SortedLists<T>HashSet<T>、 、根本不基于集合的IEnumerable<T>算法实现一起使用,...)IEnumerable

public static string GetStringOfData(IEnumerable data)
{
    var sb = new StringBuilder();
        
    foreach (object o in data) {
        sb.Append(o).Append("; ");
    }    
    if (sb.Length >= 2 ) {
        sb.Length -= 2;
    }    
    return sb.ToString();
}

这适用于几乎任何类型的集合。


注意:重写ToString具有积极的副作用,即调试器将向您显示此字符串,而不仅仅是显示类型名称。

于 2012-11-01T14:42:00.077 回答
3

您应该能够执行以下操作:

        foreach(T item in data)
        {
            var props = item.GetType().GetProperties();
            foreach(var prop in props)
            {   
                dataString += prop.GetValue(item, null);
            }
        }
于 2012-11-01T14:41:08.160 回答
1

这里有几个选项。

你可以让你所有的类都实现一些接口,比如

IDataString

其中包括从对象获取字符串数据的方法。然后您的方法可以只接受这些列表,并返回一个字符串:

public static string GetStringOfData(List<IDataString> data)
    {
        StringBuilder sb = new StringBuilder();
        foreach(var dm in data)
        {
          sb.append(dm.InterfaceMethod());
        }

        return sb.ToString()
    }

您还可以在所有对象中覆盖 ToString,并且只接受对象列表。代码将是相似的。这是假设您不介意失去正常的 ToString 功能。

你可以用refelction来做到这一点,我认为这是你在问题中所追求的,但你只是要连接所有公共字符串字段吗?这有点慢,而且更丑陋,但可以肯定。

于 2012-11-01T14:41:04.983 回答
1

首先在每个类中覆盖ToString()方法:

public class Player
{
    public int PlayerId { get; set; }
    public string PlayerName { get; set; }
    public string FavoriteThing { get; set; }
    public override string ToString()
    {
        return this.PlayerId.Tostring() + " " + PlayerName + " " + FavoriteThing;
    }
}

然后在您的方法中连接从类实例返回的所有字符串:

public static string GetStringOfData<T>(List<T> data)
        {
            StringBuilder dataBuilder = new StringBuilder();
            foreach (object o in data)
            {
                dataBuilder.Append(o.ToString());
                dataBuilder.Append(" ");
            }

            return dataBuilder.ToString();
        }

StringBuilder请注意,由于性能问题,最好使用连接字符串。

于 2012-11-01T14:43:57.857 回答
0

您期待的魔法可能是反射:在运行时确定属性并获取列表中每个项目的值。

代码如下:

public static string GetStringOfData<T>(List<T> list)
{
    var stringBuilder = new StringBuilder();

    var properties = typeof(T).GetProperties()
        .Where(p => !p.GetIndexParameters().Any());

    foreach (var item in list)
    {
        foreach (var propertyInfo in properties)
        {
            stringBuilder.AppendFormat("{0}={1};",
                                        propertyInfo.Name,
                                        propertyInfo.GetValue(item, null));
        }
        stringBuilder.AppendLine();
    }

    return stringBuilder.ToString();
}
于 2012-11-01T14:45:06.510 回答