我有以下代码,我想以一种最少的代码行编写它,并且工作方式相同。我怎样才能做到这一点?
List<Category> categoryList = new List<Category>();
categoryList = Category.LoadForProject(project.ID).ToList();
List<string> categories = new List<string>(Categories);
IList<Category> currentCategories = Category.LoadForProject(project.ID).ToList();
if (currentCategories != null)
{
foreach (var existingCategories in currentCategories)
{
if (categories.Contains(existingCategories.Name))
categories.Remove(existingCategories.Name);
else
existingCategories.Delete(Services.UserServices.User);
}
foreach (string item in categories)
{
Category category = new Category(project, item.ToString());
category.Project = project;
category.Save();
}
}
List<string> priorities = new List<string>(Priorities);
IList<Priority> currentPriorities = Priority.LoadForProject(project.ID).ToList();
if (currentPriorities != null)
{
foreach (var existingPriorities in currentPriorities)
{
if (priorities.Contains(existingPriorities.Name))
priorities.Remove(existingPriorities.Name);
else
existingPriorities.Delete(Services.UserServices.User);
}
foreach (string item in priorities)
{
Priority priority = new Priority(project, item.ToString());
priority.Project = project;
priority.Save();
}
}
答案 0 :(得分:9)
这样的事情应该这样做:
public IList<T> DoYourThing<T>(IList<T> items, IList<T> currentItems, Project project) where T : CommonBaseType
{
if (currentItems != null)
{
foreach (var existingItem in currentItems)
{
if (items.Contains(existingItem.Name))
items.Remove(existingItem.Name);
else
existingItems.Delete(Services.UserServices.User);
}
foreach (string item in items)
{
T newItem = Activator.CreateInstance(typeof(T), new object[] {project, item.ToString()}) as T;
newItem.Project = project;
newItem.Save();
}
}
return currentItems;
}
然后你可以这样称呼它:
var currentCategories = DoYourThing(Categories.ToList(), Category.LoadForProject(project.ID).ToList());
var currentProjects = DoYourThing(Priorities.ToList(), Priority.LoadForProject(project.ID).ToList());
最后,你应该特别注意两件事:
首先,函数where T : CommonBaseType
有一个通用条件。我假设Category和Project有一个包含Name的公共基类型或接口。如果没有,你应该摆脱这种情况,并使用动态获取名称。
其次,我正在使用Activator.Create为您创建类。如果你不知道那个技巧那么这很难弄清楚
祝你好运!答案 1 :(得分:7)
使优先级和类别实现相同的接口,或者从具有公共属性的类派生(即.Project,.Name和.Save)。然后使用该接口或基类作为函数的类型,并且您将能够将两个类的集合传递给它。
答案 2 :(得分:1)
好, 据我所知,您希望添加“新”列表的类别/优先级,这些列表在存储库中不存在。
制作它。
public void SaveNewItems<T>(IList<string> newList, IList<T> currentList, string project)
where T: new(), IStoreableItem
{
//find only new items
var toAdd = from itemName in newList
where !currentList.Contains(i => i.Name = itemName)
select new T {
Name = itemName,
Project = project
};
//find items to delete
var toDelete = from item in currentList
where !newList.Contains(item.Name)
select item;
toAdd.ToList().ForEach(item => item.Save());
toDelete.ToList().ForEach(item => item.Delete());
}
Category和Prio必须从包含名称,项目和保存/删除方法的IStoreableItem派生。
答案 3 :(得分:0)
如果Priority
和Category
都是从具有一组通用方法/属性的相同基类派生的,或者实现相同的接口,则可以。您只需要将Priority
和Category
的特定引用替换为对该基类或接口的引用(如果适用)。
有一些次要的代码差异(比如第一个代码块中的List<string>(Categories)
),您将不得不考虑如何处理,但是一旦祖先/接口问题,大多数代码都将落实到位已经解决了。
答案 4 :(得分:0)
我发现dynamic
对于暴露相同属性的类型集非常有用,但是没有实现相同的接口。
使用foreach(dynamic d in myList)... d.Name...
遍历列表,将其包装到方法中,并传递不同的IList<object>
个实例(类别或优先级)。
需要C#4.0。
答案 5 :(得分:0)
你需要从同一个基类派生优先级和类别......然后你可以做以下几点:
public void ProcessLists<ItemType>(Func<int, IEnumerable<ItemType>> Loader) whereItemType : CommonBase, new() {
List<string> items = new List<string>();
IList<ItemType> currentItems = Loader(project.ID).ToList();
if (currentItems != null) {
foreach (var existingItem in currentItems) {
if (items.Contains(existingItem.Name))
items.Remove(existingItem.Name);
else
existingItem.Delete(Services.UserServices.User);
}
foreach (string item in items) {
ItemType item = new ItemType();
item.Project = project
item.Name = item.ToString();
item.Save();
}
}
}
当然,有些类型(例如project.ID)只是猜测,应该用适当的行代替。
您可以通过以下方式调用优先功能:
ProcessLists<Priority>(id => Priority.LoadForProject(project.ID));