您好,
我正试图找到如何改进此代码的方法。 我想从CreateAttributes方法中删除“if”语句。 如果此属性满足某些条件,则此方法的主要思想是将属性添加到列表
internal class FildMap
{
public string ExactTargetFild { get; set; }
public string DbFild { get; set; }
public Type Type { get; set; }
}
internal static class FildMapProcessor
{
private static readonly List<FildMap> Map = new List<FildMap>();
static FildMapProcessor()
{
if(Map.Count == 0)
{
Map.Add(new FildMap {ExactTargetFild = "Address 1", DbFild = "Address1", Type = typeof (string)});
Map.Add(new FildMap { ExactTargetFild = "Date of birth", DbFild = "DateOfBirth", Type = typeof(DateTime) });
Map.Add(new FildMap { ExactTargetFild = "Wine Beer", DbFild = "pref_WineBeerSpirits", Type = typeof(bool) });
.........
}
}
public static Attribute[] CreateAttributes(this DataRow row)
{
var attributes = new List<Attribute>();
foreach (var item in Map)
{
if (item.Type == typeof(string))
{
var value = row.Get<string>(item.DbFild);
if (value != null)
attributes.Add(new Attribute{Name = item.ExactTargetFild, Value = value});
}
if (item.Type == typeof(DateTime))
{
var value = row.Get<DateTime>(item.DbFild);
if (value != DateTime.MinValue)
attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value.ToString("dd/MM/yyyy") });
}
if (item.Type == typeof(bool))
{
if (row.Contains(item.DbFild))
{
var value = row.Get<bool>(item.DbFild);
attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value.ToString() });
}
}
}
return attributes.ToArray();
}
}
谢谢,
答案 0 :(得分:6)
你可以在这里使用多态
internal abstract class FildMap
{
public string ExactTargetFild { get; set; }
public string DbFild { get; set; }
public abstract List<Attributes> GetAttributes(DataRow row);
}
internal class StringFildMap : FildMap
{
public override List<Attributes> GetAttributes(DataRow row)
{
//string specific stuff
}
}
为其他类型创建其他类
public static Attribute[] CreateAttributes(this DataRow row)
{
var attributes = new List<Attribute>();
foreach (var item in Map)
{
attributes.AddRange(item.GetAttributes(row));
}
return attributes.ToArray();
}
答案 1 :(得分:1)
switch (item.Type)
{
case typeof(string):
// code here
break;
case typeof(DateTime):
// code here
break;
case typeof(bool):
// code here
break;
}
答案 2 :(得分:1)
我认为最好重构您的代码,如下所示:
internal class FildMap
{
public string ExactTargetFild { get; set; }
public string DbFild { get; set; }
public Type Type { get; set; }
public object GetValue(object value)
{
switch(Type.Name)
{
case "System.String":
// [Code]
break;
case "System.DateTime":
// [Code]
break;
case "System.Boolean":
// [Code]
break;
}
return null;
}
}
internal static class FildMapProcessor
{
private static readonly List<FildMap> Map = new List<FildMap>();
static FildMapProcessor()
{
if (Map.Count == 0)
{
Map.Add(new FildMap { ExactTargetFild = "Address 1", DbFild = "Address1", Type = typeof(string) });
Map.Add(new FildMap { ExactTargetFild = "Date of birth", DbFild = "DateOfBirth", Type = typeof(DateTime) });
Map.Add(new FildMap { ExactTargetFild = "Wine Beer", DbFild = "pref_WineBeerSpirits", Type = typeof(bool) });
}
}
public static Attribute[] CreateAttributes(this DataRow row)
{
var attributes = new List<Attribute>();
foreach (var item in Map)
{
foreach (var item in Map)
{
var value = item.GetValue(row[item.DbFild]);
if(value != null)
attributes.Add(new Attribute { Name = item.ExactTargetFild, Value = value });
}
}
return attributes.ToArray();
}
}
答案 3 :(得分:0)
第一个质量改进是使用 else if 。对于发布的示例,这意味着同样的事情,但要更清楚一点。
对于这类事情,我更喜欢使用 if
e.g。
if(){
}
else if {
}
else if {
} else {
}
主要的选择是切换(不要执行以下操作,因为它将失败):
switch(typeof(PingItemRequestQrMsg))
{
case typeof(string):
break;
}
但结果是:
Error 1 A switch expression or case label must be a bool, char, string, integral, enum, or corresponding nullable
这意味着你需要额外的间接级别。就像您通过界面标记每个类一样,例如IMyTag返回某种枚举,或者通过辅助函数为每种类型指定id。
说真的,如果通常不是这种事情的坏选择。通常使用 if 比忍受编译时类型检查的缺乏更容易,这可能是由使用字符串方法的开关引起的。即得到一个字母错误,你的开关语句似乎不再那么酷了。
如果每个条件分支内部都有通用的东西,还有其他选项。
答案 4 :(得分:0)
您可以在类型和整数之间构建映射。然后你可以打开查找的结果。在SO上发布了另一个问题。
其中一个答案的复制部分:
Dictionary<Type, int> typeDict = new Dictionary<Type, int>
{
{typeof(int),0},
{typeof(string),1},
{typeof(MyClass),2}
};
void Foo(object o)
{
switch (typeDict[o.GetType()])
{
case 0:
Print("I'm a number.");
break;
case 1:
Print("I'm a text.");
break;
case 2:
Print("I'm classy.");
break;
default:
break;
}
}
该代码的积分转到bjax-bjax。
也许您可以考虑将查找包装到函数中以返回默认值。