The following use IEnumerable Linq Expressions. Linq is about expression building. Most implementations you'll see use anonymous delegates defined locally; however, some expressions do not need to be defined within a function scope.
The PendingMember
to Member
Select Expression/Clause below, is one such expression (Note that PendingMember
is the Mock Type I'm defining for the am
type in your code snippet). It does not require/use an instance outside of it's anonymous function scope.
Mock Models
public class SPListItem
{
public SPListItem()
{
Items = new System.Dynamic.ExpandoObject();
Items.companyCol = "Anonymous Inc.";
Items.emailCol = "[email protected]";
Items.commentCol = String.Empty;
Items.msCol = "Anonymous";
}
public int ID { get; set; }
public string Title { get; set; }
public string this[string index]
{
get { return (string)(Items as IDictionary<string, object>)[index]; }
set { (Items as IDictionary<string,object>)[index] = value; }
}
private dynamic Items { get; set; }
}
public class Member
{
public int ID { get; set; }
public string Name { get; set; }
public string Company { get; set; }
public string eMail { get; set; }
public string Comment { get; set; }
public string Membership { get; set; }
public bool IsVip { get; set; }
}
public class PendingMember
{
public int ID { get; set; }
public string Email { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public string MembershipStatus { get; set; }
}
public static dynamic GetList(string Url)
{
dynamic result = new System.Dynamic.ExpandoObject();
var list = new List<SPListItem>(new SPListItem[]
{
new SPListItem() {
ID = 0, Title = "Title 0"
},
new SPListItem() {
ID = 1, Title = "Title 1"
},
new SPListItem() {
ID = 2, Title = "Title 2"
},
new SPListItem() {
ID = 3, Title = "Title 3"
},
});
list.First()["emailCol"] = "[email protected]";
result.Items = list;
return result;
}
public class MemberManager
{
public IEnumerable<PendingMember> GetMoreMembers(string url)
{
return new PendingMember[]
{
new PendingMember()
{
FirstName = "John",
LastName = "Doe",
ID = 10,
Email = "[email protected]",
MembershipStatus = "pending"
},
new PendingMember()
{
FirstName = "Jane",
LastName = "Doe",
ID = 1,
Email = "[email protected]",
MembershipStatus = "active"
},
new PendingMember()
{
FirstName = "Jason",
LastName = "Bourne",
ID = 2,
Email = "[email protected]",
MembershipStatus = "pending"
}
}.AsEnumerable();
}
}
public static class Utilities
{
public static string ObjectToStringOrEmpty(string value)
{
return (String.IsNullOrEmpty(value)) ? "" : value;
}
}
Program Entry Point
readonly static Func<PendingMember, Member> SelectPendingMemberToMemberClause = (active) => new Member()
{
Name = active.FirstName + " " + active.LastName,
eMail = active.Email,
IsVip = true
};
static void Main(string[] args)
{
string Url = "";
string companyCol = "companyCol",
emailCol = "emailCol",
commentCol = "commentCol",
msCol = "msCol";
// this Function Delegate uses 'companyCol', 'emailCol', 'commentCol', 'msCol'.. so we're setting it locally.
Func<SPListItem, Member> SelectSPListItemToMemberClause = mItem => new Member()
{
ID = mItem.ID,
Name = mItem.Title,
Company = Utilities.ObjectToStringOrEmpty(mItem[companyCol]),
eMail = Utilities.ObjectToStringOrEmpty(mItem[emailCol]),
Comment = Utilities.ObjectToStringOrEmpty(mItem[commentCol]),
Membership = Utilities.ObjectToStringOrEmpty(mItem[msCol])
};
// the `<T> as IEnumerable<SPListItem> `cast is here only because I'm using dynamic object for the mocking..
List<Member> members = (GetList(Url).Items as IEnumerable<SPListItem>).Select(SelectSPListItemToMemberClause).ToList();
// if (DateTime.Now < row.EndDate) {
// This Function Delegate uses 'members', so we're setting it locally...
Func<PendingMember, bool> WhereActiveOrPendingStatusExcludingMembersClause = (active) => (active.MembershipStatus.ToLower() == "active" || active.MembershipStatus.ToLower() == "pending") && !(members.Any((member) => member.eMail.ToLowerInvariant() == active.Email.ToLowerInvariant()));
IEnumerable<PendingMember> cd = new MemberManager().GetMoreMembers(Url + "/");
members.AddRange(cd.Where(WhereActiveOrPendingStatusExcludingMembersClause)
.Select(SelectPendingMemberToMemberClause).ToArray());
//}
// members.ToArray();
// The next part prints to console, and is outside of the scope of this answer...
members.ForEach(member =>
{
string formatString = @"Name:= {0}, ID:= {1}, Email:= {2}, Company:= {3}, Membership:= {4}, IsVIP:= {5}, Comment:= ""{6}""";
Console.WriteLine(String.Format(formatString, member.Name, member.ID, member.eMail, member.Company, member.Membership, member.IsVip, member.Comment));
});
Console.WriteLine(value: "Press [Enter] to Proceed");
ConsoleKey key;
do
{
key = Console.ReadKey().Key;
} while (key != ConsoleKey.Enter);
}
OUTPUT
Name:= Title 0, ID:= 0, Email:= [email protected], Company:= Anonymous Inc., Membership:= Anonymous, IsVIP:= False, Comment:= ""
Name:= Title 1, ID:= 1, Email:= [email protected], Company:= Anonymous Inc., Membership:= Anonymous, IsVIP:= False, Comment:= ""
Name:= Title 2, ID:= 2, Email:= [email protected], Company:= Anonymous Inc., Membership:= Anonymous, IsVIP:= False, Comment:= ""
Name:= Title 3, ID:= 3, Email:= [email protected], Company:= Anonymous Inc., Membership:= Anonymous, IsVIP:= False, Comment:= ""
Name:= John Doe, ID:= 0, Email:= [email protected], Company:= , Membership:= , IsVIP:= True, Comment:= ""
Name:= Jason Bourne, ID:= 0, Email:= [email protected], Company:= , Membership:= , IsVIP:= True, Comment:= ""
Press [Enter] to Proceed