C# 使用泛型重构
我有一个简单的方法接口,比如C# 使用泛型重构,c#,.net,generics,C#,.net,Generics,我有一个简单的方法接口,比如 bool TryGetValue(string key, out string value); bool TryGetValue(string key, out int value); bool TryGetValue(string key, out double value); bool TryGetValue(string key, out DateTime value); // only value types
bool TryGetValue(string key, out string value);
bool TryGetValue(string key, out int value);
bool TryGetValue(string key, out double value);
bool TryGetValue(string key, out DateTime value);
// only value types allowed
//with the implementation based on dictionary<string, object>
bool TryGetValue(string key, out string value)
{
object rc;
if ( dict.TryGetValue(key, out rc) )
{
value = rc.ToString();
return true;
}
value = null;
return false;
}
bool TryGetValue(字符串键,输出字符串值);
bool TryGetValue(字符串键,out int值);
bool TryGetValue(字符串键,输出双精度值);
bool TryGetValue(字符串键,out DateTime值);
//仅允许值类型
//基于字典的实现
bool TryGetValue(字符串键,输出字符串值)
{
对象rc;
if(dict.TryGetValue(键,输出rc))
{
value=rc.ToString();
返回true;
}
值=空;
返回false;
}
看起来像是泛型的完美例子
bool TryGetValue<T>(string key, out T value) where T: ValueType;
bool TryGetValue(字符串键,out T值),其中T:ValueType;
除了无法实现func之外,还有人吗
更新-以下内容未编译,我希望避免创建多个TryGet。。。芬克斯
bool TryGetValue<T>(string key, out T value)
{
return dict.TryGetValue(key, out value) ;
}
bool TryGetValue(字符串键,out T值)
{
返回dict.TryGetValue(键,输出值);
}
试试这个:
public bool TryGetValue<T>(string key, out T value) where T : struct
{
object obj;
var result = dict.TryGetValue(key, out obj);
value = (T)obj;
return result;
}
public bool TryGetValue(字符串键,out T值),其中T:struct
{
对象对象对象;
var结果=dict.TryGetValue(输入,输出obj);
值=(T)obj;
返回结果;
}
它并不漂亮,但处理了
out
的局限性……也许有人可以把它缩短得更短?如果是这样的话,请评论……随时学习新方法。看看:它可能会对你有用。还有,为什么不扩展字典呢?我猜您想要的是:
bool TryGetValue<TValue>(string key, out TValue value)
{
object rc;
if (dict.TryGetValue(key, out rc))
{
value = (TValue)rc;
return true;
}
value = default(TValue);
return false;
}
注意-JaredPar得到了第一个答案,但似乎已经删除了他的答案,所以我取消删除我的答案,因为我认为这是OP想要的。对于任何意外的复制,我深表歉意。我相信Aaronaught已经抓住了问题的主要症结所在(捕获
对象
并向T
强制转换/取消绑定),但还有一些额外的要点:
- 要限制值类型(*),请使用
,而不是where T:struct
where T:ValueType
- …但请注意,
不是值类型,因此这可能不是一个好的“适合”string
- …和(*=)注意,
也排除了其中T:struct
可为空的
因此,我认为您只需要完全删除该约束。我可能会选择这样的约束,尽管正如Marc指出的那样,
struct
约束不允许使用字符串:
private static class Container<T> where T : struct
{
public static Dictionary<string, T> Dict = new Dictionary<string, T>();
}
public bool TryGetValue<T>(string key, out T value) where T : struct
{
return Container<T>.Dict.TryGetValue(key, out value);
}
私有静态类容器,其中T:struct
{
公共静态字典Dict=新字典();
}
公共bool TryGetValue(字符串键,out T值),其中T:struct
{
返回Container.Dict.TryGetValue(key,out值);
}
扩展方法。
namespace AssemblyCSharp
{
public static class ExtentionMethod {
public static bool TryGetValue<T, T2>(this Dictionary<T, T2> dict, string key, out T value) {
return dict.TryGetValue(key, out value);
}
}
}
namespace assemblycharp
{
公共静态类扩展方法{
公共静态bool TryGetValue(此字典dict dict、字符串键、out T值){
返回dict.TryGetValue(键,输出值);
}
}
}
业务规则-只能是基本值类型嗯,请原谅我的这一点,但基本值类型是什么?这就是msdn对值类型(结构/枚举)的说明,用户定义就是其中之一。如果存在与键关联的对象,但类型错误,则最好返回false
,而不是抛出InvalidCastException。@Anon:我可以从两个方面看到它。如果您返回false
,则字典在欺骗您;它说它没有钥匙,但它真的有。如果您有一个典型的If(!lookup.TryGetValue(key,out value)){lookup.Add(key,newValue)}
,那么它将意外失败。这取决于这个类将如何使用,不过,我可以看到,在某些情况下,简单地返回false
将是理想的结果,有没有办法在没有子类化的情况下声明dictionary where T:ValueType?@Kumar:您可以向TryGetValue
方法添加一个限制来限制输出。您可以将相同的限制添加到add
方法中(假设存在),以限制进入字典的内容。但如果您正试图创建字典的实例,则无法创建该实例。即使使用子类化,如果您创建一个字典,其中T:ValueType
,那么它只能将确切的类型T
存储为值,您不能将任何旧的对象
,根据您的问题,这是您需要能够做的。对不起,我不敢相信我编写了其中T:ValueType
。。。两次!正确的关键字是struct
,我已经更正了。@Kumar-更新了答案…希望这就是你想要的,如果没有,请告诉我你缺少了什么。
namespace AssemblyCSharp
{
public static class ExtentionMethod {
public static bool TryGetValue<T, T2>(this Dictionary<T, T2> dict, string key, out T value) {
return dict.TryGetValue(key, out value);
}
}
}