我最近开始了“编码”,这是我的第一个“项目”。它应该是一个SI转换器,在这里你可以键入一个值,它的单位和你想要它被转换到的单位。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Program
{
class Program
{
static void Main()
{
decimal one = 1;
decimal two = 0.001m;
decimal three = 0.000001m;
decimal four = 0.000000001m;
decimal five = 0.000000000001m;
decimal answer;
int y = 0;
while (y < 1)
{
Console.WriteLine("SI converter!\nPlease, enter value: ");
decimal value = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("\nFactors: \n1.One \n2.Milli(m)\n3.Micro(µ)\n4.Nano(n)\n5.Pico(p)\nEnter factor: ");
decimal factor = int.Parse(Console.ReadLine());
if (factor == 1)
{
factor = one;
}
else if (factor == 2)
{
factor = two;
}
else if (factor == 3)
{
factor = three;
}
else if (factor == 4)
{
factor = four;
}
else if (factor == 5)
{
factor = five;
}
Console.WriteLine("\nFactors: \n1.One \n2.Milli(m)\n3.Micro(µ)\n4.Nano(n)\n5.Pico(p)\nEnter the second factor: ");
decimal factor2 = Convert.ToInt32(Console.ReadLine());
if (factor2 == 1)
{
factor2 = one;
answer = value * factor;
Console.WriteLine("The answer is : " + answer);
}
else if (factor2 == 2)
{
factor2 = two;
}
else if (factor2 == 3)
{
factor2 = three;
}
else if (factor2 == 4)
{
factor2 = four;
}
else if (factor2 == 5)
{
factor2 = five;
}
answer = value * factor / factor2;
Console.WriteLine("The answer is : " + answer);
Console.WriteLine("Go again?\nY / N");
char ans = char.Parse(Console.ReadLine());
if (ans == 'n')
{
y = 8;
}
if (ans == 'y')
{
y = 0;
Console.Clear();
}
}
}
}
}
}你能给我一些关于代码和我如何改进的意见吗?
发布于 2015-12-02 18:59:35
我只是想让你的元素名和SI因子一致,比如
decimal unit = 1;
decimal milli = 0.001m;
decimal micro = 0.000001m;
decimal nano = 0.000000001m;
decimal pico = 0.000000000001m;甚至还有更像
decimal kilo = 1000.0;
decimal mega = 1000000.0;
decimal deci = 0.1m;
decimal centi = 0.01m;这将使代码的意图在有如下语句时更加可读性和简洁性:
if (factor == 1) {
factor = unit;
}此外,我还会将用户的选择和选择的因素分离到不同的变量中,例如:
int choice = Convert.ToInt32(Console.ReadLine());
switch(choice) {
case 1:
factor = unit;
break;
case 2:
factor = milli;
break;
// etc.
}明确区分用户输入和实际选择的因素。这将使代码更加可读性、可维护性和简洁性。
此外,由于您一直专门要求c#,所以可以直接将用户输入作为字符串,而不需要从数字映射:
Console.WriteLine("\nFactors: \nUnit \nMilli(m)\nMicro(µ)\nNano(n)\nPico(p)\nEnter factor: ");
string choice = Console.ReadLine();
switch(choice) {
case "Unit":
factor = unit;
break;
case "Milli":
factor = milli;
break;
// etc.
}或者从正确初始化的Dictonary<string, double>中查找因子值。
发布于 2015-12-02 20:12:17
这将是一个更长的例子,我只是在这里处理转换逻辑,因为我认为这是最有教育意义的。这也不是一个“真实世界”的例子,因为你提供的具体案例并不能证明任何接近这种结构的东西都是正当的,但是你可以很容易地发现自己在一个生产规模的应用程序中朝着这个方向前进。
我提供的代码可以用来处理输入和所需的因素。
参见转换和多代码这里
通常,创建表示属于一起的一组值的类型是一个好主意。SI倍数就是这样的例子。"nano“这个名字与它的因素有关。因为它们都构成了一个复合实体或想法,所以它们在类型(struct或class)中最有意义,这是我提供的代码中的Multiple类型。
public struct Multiple
{
public Multiple(string name, int exponent)
{
Name = name;
Exponent = exponent;
}
public string Name { get; } // Read-Only Property
public int Exponent { get; } // Read-Only Property
public double Multipler => Math.Pow(10, Exponent);
public double ConvertToBaseValue(double inputValue)
{
return inputValue/Multipler;
}
public double ConvertFromBaseValue(double inputValue)
{
return inputValue*Multipler;
}
public UnitValue CreateValue(double inputValue)
{
var newBaseValue = ConvertToBaseValue(inputValue);
return new UnitValue(this, newBaseValue);
}
public static Multiple Singular => new Multiple(null, 0);
public static Multiple Milli => new Multiple("Milli", -3);
public static Multiple Micro => new Multiple("Micro", -6);
public static Multiple Nano => new Multiple("Nano", -9);
public static Multiple Pico => new Multiple("Pico", -12);
}同样,您的输入有两个问题(值是多少?)我想看哪一个单元?)然后形成UnitValue类型的基础。如果你把这两个人分开,他们就没什么意义了。
public class UnitValue
{
public UnitValue(Multiple multiple, double baseValue)
{
Multiple = multiple;
BaseValue = baseValue;
}
public Multiple Multiple { get; }
public double PrefixedValue
{
get { return Multiple.ConvertFromBaseValue(BaseValue); }
set { BaseValue = Multiple.ConvertToBaseValue(value); }
}
public double BaseValue { get; set; }
public UnitValue ConvertTo(Multiple multiple)
{
return new UnitValue(multiple, BaseValue);
}
}默认值的
我在Multiple中添加了工厂静态方法来标准化这些值。您可能希望将所有标准定义都内置到该类型中,或者靠近它。
// Members of Multiple type.
public static Multiple Singular => new Multiple(null, 0);
public static Multiple Milli => new Multiple("Milli", -3);
public static Multiple Micro => new Multiple("Micro", -6);
public static Multiple Nano => new Multiple("Nano", -9);
public static Multiple Pico => new Multiple("Pico", -12);
// Allows you to get multiples like so.
var m = Multiple.Milli;
var u = Multiple.Micro;每个人都会一遍又一遍地说。在这里,我认为这是通过避免使用所有这些零输入乏味的值来证明的。它还避免了我有0.0001的milli前缀的bug。
// Risky
public static Multiple Pico => new Multiple("Pico", 0.000000000001);
// Safer
public static Multiple Pico => new Multiple("Pico", -12);我没有让用户使用特殊的方法来更新基值或前缀值,而是决定将BaseValue属性变成一个自动属性(这意味着我不需要为gettor和settors编写样板代码),并将PrefixedValue连接到它上。通过这种方式,您可以使该类型的用户的生活更容易一些,代价是让他们知道什么时候使用不同的值以及为什么。
public double PrefixedValue
{
get { return Multiple.ConvertFromBaseValue(BaseValue); }
set { BaseValue = Multiple.ConvertToBaseValue(value); }
}因为Multiple数据类型属于一起,所以客户机更新它们没有任何意义。因此,为了防止数据损坏,我让它们只获得在对象实例化时设置的属性。
// Constructor assigns the values when instantiated.
public Multiple(string name, int exponent)
{
Name = name;
Exponent = exponent;
}
public string Name { get; } // Can only be set when instantiated.
public int Exponent { get; } // Can only be set when instantiated.当你继续前进的时候,这些是你想要考虑的事情。我跳过了其他一些需要理解的重要事情,但它们可以等到你有了更多的经验之后:
我希望那不是太可怕!如果有人有任何反馈的话,我很想听听。
如果使用我编写的类,我已经修改了我在这里的主旨,以包括主程序的一个示例。除了删除复制和将登录的细节推入Log方法之外,我没有在那里进行完整的重构练习。
的确如此。但你还在到处重复。想象一下,如果你想改变你记录东西的方式?还是添加标准格式?
如果您使实现远离日志记录函数的用户,那么您可以随时更改它。如果您想用日志文件替换控制台日志功能,可以在一个地方更改它。如果没有这个抽象,您就需要更新几十个引用。
// "Brittle" Code
Console.WriteLine("Bob"); // In one file
Console.WriteLine("Says"); // In another file
Console.WriteLine("Hi!"); // In a third file
// Abstracted Code
Log("Bob");
Log("Bob");
private static void Log(string message)
{
Console.WriteLine(message);
}最后一件您还想考虑的事情是,如果用户输入了一些奇怪的内容,会发生什么。此示例不包括用户条目周围的任何错误处理。
https://codereview.stackexchange.com/questions/112636
复制相似问题