当返回不同的类型时,是否建议使用多种方法
本文关键字:方法 是否 返回 类型 | 更新日期: 2023-09-27 17:58:22
我从Entity
对象返回值。它们有的是String
型的,有的不是。现在,我做了一个快速的解决方案如下。
private String GetStringValue(Entity entity, String attribute, String substitute = "")
{
if(entity.Contains(attribute)
return entity[attribute] as String;
return substitute;
}
private String GetIntValue(Entity entity, String attribute, int substitute = 0)
{
if(entity.Contains(attribute)
return entity[attribute] as int;
return substitute;
}
然后我想起了泛型类型有一个语法(类似于<TypeX>
)。然而,我的问题是,是否有必要开始更改现有代码。我需要在两个地方更改方法的签名(返回类型和替换类型),但我担心我也需要在方法内部进行一些复杂的编码。
另一方面,我有一个很好的方法来处理所有可能的类型(我有预感,我们将处理的不仅仅是字符串和整数。
您必须在三个位置更改方法的签名,因为您还必须添加泛型参数:
private T GetValue<T>(Entity entity, String attribute, T substitute)
在方法中,不需要任何复杂的编码;将当前出现的string
或int
分别替换为T
就足够了。(请注意,只有当您将T
限制为引用类型时,才能应用as
运算符——您可能不想这样做,因为int
是一种值类型)。
请注意,这种方法有两个问题,您可能会认为它们有缺点:
- 这个通用方法将支持"所有可能的类型",但它也将支持任何类型impossible(用户可以自由地为
T
指定他们喜欢的任何类型,并且在仍然支持string
和int
的情况下无法限制T
- 不能为每种类型指定任意的默认替换值。您可以为
substitute
声明一个默认值,即default(T)
,但至少对于string
,它不是空字符串,而是null
你说得对,"something like"是泛型方法。查看那里的通用方法。下一个方法看起来很适合您的目的。
private static T GetValue<T>(Entity entity, string attribute, T defaultValue)
{
if (!entity.Contains(attribute))
return defaultValue;
return (T)entity[attribute];
}
编辑:根据w0lf的评论更新。
如果不想更改方法签名,可以编写一个泛型函数,并从所有这些非泛型版本中调用它。
private String GetStringValue(...){
return GetValue<String>(...);
}
顺便说一句,你正在寻找通用方法
例如(来自msdn)
static void Swap<T>(ref T lhs, ref T rhs)
{
T temp;
temp = lhs;
lhs = rhs;
rhs = temp;
}
...
Swap<int>(ref a, ref b);
或者只是
Swap(ref a, ref b); //type int is infered based on type of arguements and method signature
Entity
是什么类?假设它是一个自定义类,使它也是通用的,那么它就起作用了:
private T Get<T>(Entity<T> entity, T attribute, T substitute = default(T))
{
if (entity.Contains(attribute))
return entity[attribute];
return substitute;
}
您可以通过以下方式检索值:
var entity = new Entity<string>();
string val = Get<string>(entity, "attr", "subst");
您应该定义Entity<T>
类:
public class Entity<T>
{
// TODO: implement
public T this[string i] { get; set; }
// TODO: implement
internal bool Contains(string attribute)
{
return true;
}
// TODO: implement
// other properties and methods
}
你可以使用一种通用的方法:
private T GetStringValue<T>(Entity<T> entity, String attribute, T substitute = default(T))
{
if (entity.Contains(attribute))
return entity[attribute];
return substitute;
}
如果可以在方法中泛化代码,我绝对建议以通用的方式使用它。它使类更小,可读性更好,如果需求发生变化,您只需要更改一个方法。您的方法看起来可以很容易地实现泛型。
private T GetIntValue<T>(Entity entity, String attribute, T substitute = default(T))
{
if(entity.Contains(attribute))
return (T)entity[attribute];
return substitute;
}
如果有更多的逻辑要执行,你也可以使用一个字典,其中包含不同类型的函数:
private IDictionary<Type, Func<Entity, string, object>> actions;
private void InitActions()
{
actions = new Dictionary<Type, Func<Entity, string, object>>
{
{
typeof (string), (entity, attribute) =>
{
// this could be your custom code for string
return entity[attribute];
}
},
{
typeof (int), (entity, attribute) =>
{
// this could be your custom code for int
return entity[attribute];
}
}
};
}
private T GetIntValue<T>(Entity entity, String attribute, T substitute = default(T))
{
if (entity.Contains(attribute) && actions.ContainsKey(typeof (T)))
{
Func<Entity, string, object> action = actions[typeof (T)];
return (T)action(entity, attribute);
}
return substitute;
}