我该如何重构这段代码?
我有.net 3.5,我想制定一个通用方法。我该如何重构这段代码?
case (int)Enums.SandwichesHoagies.Cheeses:
if (this.Cheeses.Where(x => x.Id == product.ProductId).SingleOrDefault() == null)
{
var newCheese = new Cheese
{
Id = product.ProductId,
Name = product.Name,
PriceValue = product.Price.HasValue ? (double)product.Price.Value : 0.00
};
this.Cheeses.Add(newCheese);
}
else
{
foreach (var cheese in this.Cheeses.Where(cheese => cheese.Id == product.ProductId))
{
this.Cheeses.Remove(cheese);
break;
}
}
foreach (var cheese in Cheeses) cheese.Type = string.Empty;
if (this.Cheeses.Count > 0) Cheeses.First().Type = "Cheeses:";
break;
case (int)Enums.SandwichesHoagies.Meats:
if (this.Meats.Where(x => x.Id == product.ProductId).SingleOrDefault() == null)
{
var newMeat = new Meat
{
Id = product.ProductId,
Name = product.Name,
PriceValue = product.Price.HasValue ? (double)product.Price.Value : 0.00
};
this.Meats.Add(newMeat);
}
else
{
foreach (var meat in this.Meats.Where(meat => meat.Id == product.ProductId))
{
this.Meats.Remove(meat);
break;
}
}
foreach (var meat in Meats) meat.Type = string.Empty;
if (this.Meats.Count > 0) Meats.First().Type = "Meats:";
break;
i have .net 3.5 and i would like to make a generic method. how do i refactor this code?
case (int)Enums.SandwichesHoagies.Cheeses:
if (this.Cheeses.Where(x => x.Id == product.ProductId).SingleOrDefault() == null)
{
var newCheese = new Cheese
{
Id = product.ProductId,
Name = product.Name,
PriceValue = product.Price.HasValue ? (double)product.Price.Value : 0.00
};
this.Cheeses.Add(newCheese);
}
else
{
foreach (var cheese in this.Cheeses.Where(cheese => cheese.Id == product.ProductId))
{
this.Cheeses.Remove(cheese);
break;
}
}
foreach (var cheese in Cheeses) cheese.Type = string.Empty;
if (this.Cheeses.Count > 0) Cheeses.First().Type = "Cheeses:";
break;
case (int)Enums.SandwichesHoagies.Meats:
if (this.Meats.Where(x => x.Id == product.ProductId).SingleOrDefault() == null)
{
var newMeat = new Meat
{
Id = product.ProductId,
Name = product.Name,
PriceValue = product.Price.HasValue ? (double)product.Price.Value : 0.00
};
this.Meats.Add(newMeat);
}
else
{
foreach (var meat in this.Meats.Where(meat => meat.Id == product.ProductId))
{
this.Meats.Remove(meat);
break;
}
}
foreach (var meat in Meats) meat.Type = string.Empty;
if (this.Meats.Count > 0) Meats.First().Type = "Meats:";
break;
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
假设有两件事:
Meat
和Cheese
继承自Ingredient
或实现IIngredient
Meats
和Cheeses
集合是IList
这里我们开始:
Assuming two things:
Meat
andCheese
inherit fromIngredient
or implementIIngredient
Meats
andCheeses
collections areIList<T>
Here we go:
乍一看,您有一些可以访问的常用属性:
Id、Name、PriceValue 和 Type
。对我来说,这看起来像是一个基类或接口。这样,您可以首先将代码重构为方法,在这种情况下,当您引用
this.Meats
或this.Cheeses
时,您应该引用list
,当您引用Meat
或Cheese
实例时,只需引用T
即可。看看这能让你走多远并进一步重构。
At initial glance, you have some common properties you access,
Id, Name, PriceValue, and Type
. That looks like a base class or interface to me. With that, you could start by refactoring your code into a methodIn which case, where you refer to
this.Meats
orthis.Cheeses
, you would instead refer tolist
, and where you refer to instances ofMeat
orCheese
, you simply refer toT
.See how far that gets you and refactor further.
如果不知道所使用的类型(和基本类型/接口),就很难知道您的确切要求。我假设你正在使用某种 ORM,它无论如何都会吐出部分类。
使其易于使用的第一个要求是 Meat 和 Cheese 共享一个公共接口(或抽象类)。这应该是这样的基本内容。
使用分部类的假设使得扩展您的类以使用此接口变得容易。
我发现有趣的是,您有一种不同类型的产品,它具有不同的字段名称,但功能几乎相同。您是否应该保留与上述接口相同的名称,并使其也从该接口派生?不管怎样,假设你拥有的是这样的东西。
您要做的第一件事是使用工厂模式来创建特定产品。
new()
约束需要 Cheese 和 Meat 类中的无参数构造函数。我认为这没有问题。您只需要调用.Create(product);
接下来的部分,我需要假设您的 Cheeses 和 Meats 对象(或属性)也共享一个公共类(
ICollection
),或者您可以根据特定需求定义自己的。检查产品是否存在的通用方法
我对您在 foreach 循环内调用
.Remove
的想法表示怀疑。修改集合可能会导致用于循环遍历集合的枚举器出现问题。如果这是一个问题,我会找到更好的方法。Hard to know your exact requirements without knowing the types (and base types/interfaces) used. I'm going to assume you're using some kind of ORM which spits out partial classes anyway.
First requirement to make this easy to work with, is that Meat and Cheese share a common interface (or abstract class). This should be something basic like this.
The assumption that partial classes are used makes it easy to extend your class to use this interface.
I find it interesting that you have a different kind of Product which has different field names, but almost the same features. Should you perhaps keep the names the same as the above interface and make this also derived from the interface? Anyway, assuming what you have is something like this.
The first thing you wanna do is use the Factory Pattern to create a specific product.
The
new()
constraint requires a parameterless constructor in your Cheese and Meat classes. I assume this is no problem. You just need to call.Create<Cheese>(product);
The next parts, I would need to assume that your Cheeses and Meats objects (or properties), also share a common class (
ICollection<IProduct>
), or you could define your own for particular needs.A generic method to check if a product exists
I'm skeptical of your idea of calling
.Remove
inside a foreach loop. Modifying a collection can cause problems for the enumerator being used to loop through it. I would find a better approach to that if it's a concern.