C# 这个代码有多糟糕?
好的,我是一个业余程序员,刚刚写了这个。它完成了任务,但我想知道它有多糟糕,可以做什么样的改进 [请注意,这是涂鸦CMS的粉笔扩展。]C# 这个代码有多糟糕?,c#,.net,asp.net,graffiticms,C#,.net,Asp.net,Graffiticms,好的,我是一个业余程序员,刚刚写了这个。它完成了任务,但我想知道它有多糟糕,可以做什么样的改进 [请注意,这是涂鸦CMS的粉笔扩展。] public string PostsAsSlides(PostCollection posts, int PostsPerSlide) { StringBuilder sb = new StringBuilder(); decimal slides = Math.Round((decimal)posts.Count /
public string PostsAsSlides(PostCollection posts, int PostsPerSlide)
{
StringBuilder sb = new StringBuilder();
decimal slides = Math.Round((decimal)posts.Count / (decimal)PostsPerSlide, 3);
int NumberOfSlides = Convert.ToInt32(Math.Ceiling(slides));
for (int i = 0; i < NumberOfSlides; i++ )
{
int PostCount = 0;
sb.Append("<div class=\"slide\">\n");
foreach (Post post in posts.Skip<Post>(i * PostsPerSlide))
{
PostCount += 1;
string CssClass = "slide-block";
if (PostCount == 1)
CssClass += " first";
else if (PostCount == PostsPerSlide)
CssClass += " last";
sb.Append(string.Format("<div class=\"{0}\">\n", CssClass));
sb.Append(string.Format("<a href=\"{0}\" rel=\"prettyPhoto[gallery]\" title=\"{1}\"><img src=\"{2}\" alt=\"{3}\" /></a>\n", post.Custom("Large Image"), post.MetaDescription, post.ImageUrl, post.Title));
sb.Append(string.Format("<a class=\"button-launch-website\" href=\"{0}\" target=\"_blank\">Launch Website</a>\n", post.Custom("Website Url")));
sb.Append("</div><!--.slide-block-->\n");
if (PostCount == PostsPerSlide)
break;
}
sb.Append("</div><!--.slide-->\n");
}
return sb.ToString();
}
公共字符串PostsAsSlides(PostCollection posts,int PostsPerSlide)
{
StringBuilder sb=新的StringBuilder();
十进制幻灯片=数学四舍五入((十进制)posts.Count/(十进制)PostsPerSlide,3);
int NumberOfSlides=Convert.ToInt32(数学上限(幻灯片));
对于(int i=0;i
这不太好,但我见过更糟的情况
假设这是ASP.Net,您使用这种方法而不是中继器有什么原因吗
编辑:
如果在本例中无法使用转发器,我建议使用.NETHTML类来生成HTML,而不是使用文本。稍后阅读/调整会更容易一些。如果存在帖子的定义,这会有所帮助,但一般来说,我会说,在Asp.Net中,在代码隐藏中生成HTML不是一种方法 因为它被标记为.Net,所以 要显示集合中的项目列表,最好查看其中一个数据控件(中继器、数据列表等),并学习如何正确使用这些控件
我见过更糟的情况,但你可以改进很多
你可以做的另一件事是:用
sb.AppendFormat(…)
代替sb.Append(string.Format(…)
调用
foreach (Post post in posts.Skip<Post>(i * PostsPerSlide))
{
// ...
if (PostCount == PostsPerSlide)
break;
}
事实上,您的两个嵌套循环可能可以在一个循环中处理
另外,我更喜欢对html属性使用单引号,因为它们是合法的,不需要转义。我的第一个想法是,这将很难进行单元测试 我建议将第二个for循环作为一个单独的函数,这样您就可以得到如下结果:
for (int i = 0; i < NumberOfSlides; i++ )
{
int PostCount = 0;
sb.Append("<div class=\"slide\">\n");
LoopPosts(posts, i);
...
如果您养成了这样做循环的习惯,那么当您需要进行单元测试时,将内部循环与外部循环分开进行测试将更容易。使用而不是StringBuilder来编写HTML:
StringBuilder sb = new StringBuilder();
using(HtmlTextWriter writer = new HtmlTextWriter(new StringWriter(sb)))
{
writer.WriteBeginTag("div");
writer.WriteAttribute("class", "slide");
//...
}
return sb.ToString();
我们不希望使用非结构化编写器来编写结构化数据
将你的内循环主体分成一个单独的例行程序:
foreach(...)
{
WritePost(post, writer);
}
//snip
private void WritePost(Post post, HtmlTextWriter writer)
{
//write single post
}
这使得它更易于测试和修改
使用数据结构来管理CSS类等内容。
不要在额外的类名后面加空格,希望所有的类名都排在最后,而是保留一个列表
,根据需要添加和删除类名,然后调用:
List<string> cssClasses = new List<string>();
//snip
string.Join(" ", cssClasses.ToArray());
List cssClasses=new List();
//剪断
Join(“,cssClasses.ToArray());
我想说,它看起来足够好了,代码没有严重的问题,而且可以很好地工作。但这并不意味着它无法改进
以下是一些提示:
对于一般浮点运算,应使用double
而不是Decimal
。但是,在这种情况下,您根本不需要任何浮点运算,只需要整数即可:
int numberOfSlides = (posts.Count + PostsPerSlide - 1) / PostsPerSlide;
但是,如果只对所有项目使用单个循环,而不是循环中的循环,则根本不需要幻灯片计数
局部变量的约定是驼峰式(后点)而不是帕斯卡式(后计数)。尽量使变量名有意义,而不是像“sb”这样晦涩难懂的缩写。如果一个变量的作用域很小,你不需要一个有意义的名字,只需要一个尽可能简单的字母,而不是缩写
您可以直接指定文字字符串,而不是将字符串“滑块”和“第一个”连接起来。这样,您就可以用一个简单的赋值替换对String.Concat的调用。(这接近于过早优化,但另一方面,字符串串联所需的时间要长约50倍。)
您可以在StringBuilder上使用.AppendFormat(…)
而不是.Append(String.Format(…)
。在这种情况下,我会坚持使用Append,因为实际上没有任何东西需要格式化,您只是连接字符串
所以,我会这样写方法:
public string PostsAsSlides(PostCollection posts, int postsPerSlide) {
StringBuilder builder = new StringBuilder();
int postCount = 0;
foreach (Post post in posts) {
postCount++;
string cssClass;
if (postCount == 1) {
builder.Append("<div class=\"slide\">\n");
cssClass = "slide-block first";
} else if (postCount == postsPerSlide) {
cssClass = "slide-block last";
postCount = 0;
} else {
cssClass = "slide-block";
}
builder.Append("<div class=\"").Append(cssClass).Append("\">\n")
.Append("<a href=\"").Append(post.Custom("Large Image"))
.Append("\" rel=\"prettyPhoto[gallery]\" title=\"")
.Append(post.MetaDescription).Append("\"><img src=\"")
.Append(post.ImageUrl).Append("\" alt=\"").Append(post.Title)
.Append("\" /></a>\n")
.Append("<a class=\"button-launch-website\" href=\"")
.Append(post.Custom("Website Url"))
.Append("\" target=\"_blank\">Launch Website</a>\n")
.Append("</div><!--.slide-block-->\n");
if (postCount == 0) {
builder.Append("</div><!--.slide-->\n");
}
}
return builder.ToString();
}
公共字符串PostsAsSlides(PostCollection posts,int postsPerSlide){
StringBuilder=新的StringBuilder();
int postCount=0;
foreach(以职位为单位的职位){
后计数++;
字符串cssClass;
如果(后计数==1){
生成器。追加(“\n”);
cssClass=“滑块优先”;
}else if(postCount==postsPerSlide){
cssClass=“滑块最后一个”;
后计数=0;
}否则{
cssClass=“滑块”;
}
builder.Append(“\n”)
美联社
int numberOfSlides = (posts.Count + PostsPerSlide - 1) / PostsPerSlide;
public string PostsAsSlides(PostCollection posts, int postsPerSlide) {
StringBuilder builder = new StringBuilder();
int postCount = 0;
foreach (Post post in posts) {
postCount++;
string cssClass;
if (postCount == 1) {
builder.Append("<div class=\"slide\">\n");
cssClass = "slide-block first";
} else if (postCount == postsPerSlide) {
cssClass = "slide-block last";
postCount = 0;
} else {
cssClass = "slide-block";
}
builder.Append("<div class=\"").Append(cssClass).Append("\">\n")
.Append("<a href=\"").Append(post.Custom("Large Image"))
.Append("\" rel=\"prettyPhoto[gallery]\" title=\"")
.Append(post.MetaDescription).Append("\"><img src=\"")
.Append(post.ImageUrl).Append("\" alt=\"").Append(post.Title)
.Append("\" /></a>\n")
.Append("<a class=\"button-launch-website\" href=\"")
.Append(post.Custom("Website Url"))
.Append("\" target=\"_blank\">Launch Website</a>\n")
.Append("</div><!--.slide-block-->\n");
if (postCount == 0) {
builder.Append("</div><!--.slide-->\n");
}
}
return builder.ToString();
}