我有问题正确地打破这些嵌套循环。代码尝试做的是表明客户已经租借了某部电影。将电影和客户都与arraylist对象的属性进行比较,然后如果全部检出name属性,则将电影对象的ID属性作为字符串添加到另一个arraylist。只要我使用第一部电影(来自电影)和第一部客户(来自客户),所有这一切都能正常工作,但如果我尝试将其他电影与其他客户一起租借到我的arraylist,那么它将租借的电影添加到customerRentedMovies arraylist但打印出“其他消息”。我想我还需要打破foreach(blabla)循环吗?或者可以使用?评论被删除(看起来有点混乱,如果需要可以进一步解释)
public void RentMovie(string titel, int movieID, string name, int customerID)
{
foreach (Customer customer in customers)
{
if (name == customer.Name && customerID == customer.CustomerID)
{
foreach (MovieInfo movie in movies)
{
if (titel == movie.Titel && movieID == movie.MovieID)
{
movie.rented = true;
string rentedMovie = string.Format("{0} ID: {1}", movie.Titel, movie.MovieID);
customer.customerRentedMovies.Add(rentedMovie);
break;
}
else { Console.WriteLine("No movie with that titel and ID!"); }
}
break;
}
else { Console.WriteLine("No customer with that ID and name"); }
}
}
答案 0 :(得分:4)
让我觉得实际上根本不需要嵌套循环 - 无论如何你都不会根据movies
改变customer
。另外,我使用LINQ。所以:
var customer = customers.FirstOrDefault(c => c.Name == customerName &&
c.CustomerId == customerId);
if (customer == null)
{
Console.WriteLine("No customer with that ID and name");
return;
}
var movie = movies.FirstOrDefault(m => m.Name == movieName &&
m.MovieId == movieId);
if (movie == null)
{
Console.WriteLine("No movie with that ID and name");
return;
}
movie.rented = true;
string rentedMovie = string.Format("{0} ID: {1}", movie.Titel, movie.MovieID);
customer.customerRentedMovies.Add(rentedMovie);
(如果无法找到客户或电影,我可能实际更改返回的内容或抛出异常,但这是另一回事。)
重要的是,现在没有明确的循环 - 我们说我们试图找到声明性并采取相应的行动。同样地,没有嵌套,这将两个问题分开(找一部电影并找到一个顾客)。我们现在可以轻松地将每个部分提取到一个单独的方法中 - 特别是如果我们使用异常而不是记录和返回。那就是:
Customer customer = FindCustomer(customerId, customerName);
Movie movie = FindMovie(movieId, movieName);
movie.rented = true;
string rentedMovie = string.Format("{0} ID: {1}", movie.Titel, movie.MovieID);
customer.customerRentedMovies.Add(rentedMovie);
更简单。
答案 1 :(得分:2)
您的方法违反了“单一责任”规则 - 每个类别或方法都应该只有一个责任和更改原因。你有一个方法负责做3件不同的事情:
这使它
这是Code Smell。
您应该像这样重构您的方法,将寻找客户和查找电影的责任委托给他们自己的方法:
public void RentMovie( string titel , int movieID , string name , int customerID )
{
Customer customer = FindCustomer( customerID , name ) ;
MovieInfo movie = FindMovie( movieID , titel ) ;
if ( customer == null )
{
Console.WriteLine("No customer with that ID and name");
}
if ( movie == null )
{
Console.WriteLine("No movie with that titel and ID!") ;
}
if ( customer != null && movie != null )
{
string rentedMovie = string.Format( "{0} ID: {1}" , movie.Titel , movie.MovieID );
movie.rented = true;
customer.customerRentedMovies.Add( rentedMovie );
}
return ;
}
如果您不使用Linq,FindCustomer()
和FindMovie
方法可能如下所示:
private MovieInfo FindMovie( int movieID , string titel )
{
MovieInfo instance = null ;
foreach( MovieInfo movie in movies )
{
if ( movie.MovieID == movieID && movie.Titel == titel )
{
instance = movie ;
break ;
}
}
return instance ;
}
private Customer FindCustomer( int customerID , string name )
{
Customer instance = null ;
foreach( Customer customer in customers )
{
if ( customer.CustomerID == customerID && customer.Name == name )
{
instance = customer ;
break ;
}
}
return instance ;
}
如果您使用Ling,则可能采用相同的方法:
private MovieInfo FindMovie( int movieID , string titel )
{
return movies.Where( x => x.MovieID == movieID && x.Titel == titel ).SingleOrDefault() ;
}
private Customer FindCustomer( int customerID , string name )
{
return customers.Where( x => x.Name == name && x.CustomerID == customerID ).SingleOrDefault() ;
}
现在代码更简单,更易于理解和自我描述。在进行更改时,更改也会更容易。
答案 2 :(得分:1)
如果您想要摆脱两个循环,只需使用return
。
foreach (Customer customer in customers)
{
if (name == customer.Name && customerID == customer.CustomerID)
{
foreach (MovieInfo movie in movies)
{
if (titel == movie.Titel && movieID == movie.MovieID)
{
movie.rented = true;
string rentedMovie = string.Format("{0} ID: {1}", movie.Titel, movie.MovieID);
customer.customerRentedMovies.Add(rentedMovie);
return; //break out of both loops
}
else { Console.WriteLine("No movie with that titel and ID!"); }
}
}
else { Console.WriteLine("No customer with that ID and name"); }
}
答案 3 :(得分:1)
由于你在循环后没有做任何事情,你只需拨打return;
即可获得休息时间。
答案 4 :(得分:0)
如果您能够使用LINQ,您的代码可以变得更加清晰:
var customer =
customers.FirstOrDefault(x => x.Name == name && x.CustomerID == customerID);
if (customer == null) { // Error }
var movie = movies.FirstOrDefault(x => x.Title == title && x.MovieID == movieID);
if (movie == null) { // Error }
// Rental logic here
另外,ID不足以唯一地标识对象吗?
答案 5 :(得分:0)
如果您只想在“for”循环结束时显示错误,您需要设置某种标记,表示您找不到电影或其他内容。我已经改变了你的代码:
public void RentMovie(string titel, int movieID, string name, int customerID)
{
bool hasCustomer, hasMovie;
hasCustomer = false;
hasMovie = false;
foreach (Customer customer in customers)
{
if (name == customer.Name && customerID == customer.CustomerID)
{
hasCustomer = true;
foreach (MovieInfo movie in movies)
{
if (titel == movie.Titel && movieID == movie.MovieID)
{
hasMovie = true;
movie.rented = true;
string rentedMovie = string.Format("{0} ID: {1}", movie.Titel, movie.MovieID);
customer.customerRentedMovies.Add(rentedMovie);
break;
}
}
if (hasMovie == false) {
Console.WriteLine("No movie with that titel and ID!");
}
break;
}
}
if (hasCustomer == false) {
Console.WriteLine("No customer with that ID and name");
}
}
答案 6 :(得分:0)
如果您有25个客户,那么第一个foreach中的If / Else将会受到每个客户的影响,那么它会在找到合适的客户之前点击其他语句10次(假设合适的客户是第11个)为什么不使用linq来获取和设置值
Customer customer = customers.FirstOrDefault(x => x.Name = name && x.CustomerID = customerID);
if(customer != null) //will be null if customer isn't found
{
//DO the same thing here for the movies and once you find the
//movie set the properties and add to the collection
}