0

我试图编写一种方法,将任何 IList 的事物转换为这些事物的逗号分隔列表作为字符串。它看起来像这样:

public static string ToStringList<T>(this T source) where T : IList<object>
{
    string list_string = "[EMPTY]";
    try
    {
        if (source != null && source.Count() > 0)
        {
            list_string = "";
            foreach (var item in source)
            {
                //ToString unnecessarily written here to highlight the usage
                list_string += $", {item.ToString()}";
            }
        }
    }
    catch
    {
        list_string = "[ERROR - could not list values]";
    }
    list_string = list_string.StartsWith(", ") ? list_string.Substring(2) : list_string;
    return list_string;
}

我想在可观察的站点集合上使用此方法:

public class Site
{
    public string Name { get; set; }
    public string code { get; set; }

    public override string ToString()
    {
        return Name;
    }
}

但是,当我尝试运行以下代码时,出现转换错误:

public ObservableCollection<Site> SelectedSites {get;set;}
//[some skipped code that inserts values into the ObservableCollection]

//Error: Cannot convert from Site to object
var sites = SelectedSites.ToStringList();

我明白为什么会出现转换错误 - 代码无法知道如何Siteobject. 但是,鉴于ToString()一切都存在,有没有办法可以改变方法ToStringList(),使其可以接受任何类型的 IList?

我已经阅读了一些关于 IList 的文章和页面(比如thisthis),但老实说,他们既困惑又开明——因为我所问的问题是不可能的或冗长以至于不切实际(在这种情况下,我可以找到另一个方法)?

我正在使用 .NET Framework 4.8。

4

2 回答 2

2

您的扩展方法在 an 上不可用ObservableCollection<Site>,因为 anIList<Site>根本不相关IList<object>(请参阅此处了解原因)。

您可以改为IList<T>用作参数类型:

public static string ToStringList<T>(this IList<T> source)

现在这将可用ObservableCollection<Site>,因为它实现了,编译器IList<Site>可以推断出来。TSite

由于您没有使用IList<T>提供的任何特定内容,因此您还可以将此方法定义为更通用的IEnumerable<T>. 但是,调用Count()将军IEnumerable可能是 O(n) 操作。您可能想用它Any()来检查是否有任何元素。

public static string ToStringList<T>(this IEnumerable<T> source)

另请注意,您似乎正在重新发明string.Join一点:

public static string ToStringList<T>(this IEnumerable<T> source)
{
    try
    {
        const string empty = "[EMPTY]";
        if (source != null)
        {
            return string.Join(", ", source.Select(x => x.ToString()).DefaultIfEmpty(empty));
        }
        else
        {
            return empty;
        }
    }
    catch
    {
        return "[ERROR - could not list values]";
    }
}
于 2021-06-17T10:34:57.190 回答
2

改变

public static string ToStringList<T>(this T source) where T : IList<object>

public static string ToStringList<T>(this IList<T> source) where T : class
于 2021-06-17T10:34:05.213 回答