Finally, you can see the string shared by the netizen. join tips, I think of my first child, because of string. the join operation can only be performed on the string comment column, and cannot be performed on a set such as list, able, and iqueryable. Therefore, I have created an extension to facilitate myself, so that join can be used for a set like a string.
Usage
IEnumerable source = null;
source.Join();
source.Join("PropertyName",",");
source.Join(separator: "|");
Original shard
Under iterateextension. CS
/// <summary>
/// Operations on counter objects, such as collections and counter columns.
/// </summary>
public static class IterateExtension
{
/// <summary>
/// Combine the object attribute columns into a string, and use the attribute name of the object to obtain the attribute value of the object.
/// </summary>
/// <Param name = "Source"> columns can be used as the source. </param>
/// <Param name = "propertyname"> property name of an object </param>
/// <Param name = "separator"> separator string </param>
/// <returns></returns>
public static string Join(this IEnumerable source, string propertyName = null, string separator = ",")
{
if (source == null)
{
return null;
}
bool nullProperty = propertyName == null;
StringBuilder sb = new StringBuilder();
PropertyDescriptor pi = null;
Type type = null;
foreach (object value in source)
{
if (value == null)
{
continue;
}
if (value is string || nullProperty)
{
// If the value is string or the propertyname is null, it is directly exported.
sb.Append(value);
}
else if (value is DataRow)
{
sb.Append(((DataRow)value)[propertyName]);
}
else
{
Type temp = value.GetType();
if (type != temp)
{
type = temp;
// Use typedescriptor. getproperties (object) to obtain the atomicity of icustomtypedescriptor, which can be customized, for example, datarowviw.
// If typedescriptor. getproperties (type) is used, icustomtypedescriptor is not judged.
pi = TypeDescriptor.GetProperties(value)[propertyName];
if (pi == null)
{
throw new InvalidOperationException(string.Format("{0} Property {1} Not Exist.", type, propertyName));
}
}
sb.Append(pi.GetValue(value));
}
sb.Append(separator);
}
return (separator == null || sb.Length == 0) ? sb.ToString() : sb.ToString(0, sb.Length - separator.Length);
}
}
Single-dollar renewal
public class Test
{
public string P1 { get; set; }
public int P2 { get; set; }
public override string ToString()
{
return this.P1;
}
}
[TestMethod()]
public void JoinTest()
{
IEnumerable source = null;
//String
source = new string[] { "A", "B", "C" };
Assert.AreEqual(source.Join(), "A,B,C");
Assert.AreEqual(source.Join(separator : "|"), "A|B|C");
//List + class
source = new List<Test> { new Test() { P1 = "A", P2 = 1 }, new Test() { P1 = "B", P2 = 2 }, new Test() { P1 = "C", P2 = 3 } };
Assert.AreEqual(source.Join(), "A,B,C");
Assert.AreEqual(source.Join("P2"), "1,2,3");
//DataTable And DataView
DataTable dt = new DataTable();
dt.Columns.Add("Col1");
dt.Columns.Add("Col2");
dt.Rows.Add("A", 1);
dt.Rows.Add("B", 2);
dt.Rows.Add("C", 3);
Assert.AreEqual(dt.Rows.Join("Col1"), "A,B,C");
Assert.AreEqual(dt.Rows.Join("Col2"), "1,2,3");
Assert.AreEqual(dt.DefaultView.Join("Col1"), "A,B,C");
Assert.AreEqual(dt.DefaultView.Join("Col2"), "1,2,3");
//IQueryable
TestDataContext db = new TestDataContext();
source = (from e in db.Employers
select e).Take(3);
Assert.AreEqual(source.Join("Name"), "A,B,C");
}
Limit: Originally in 2008, the method has more than one limit. If it is changed to 2010, it is changed to use the limit parameter.