Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/280.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为未知类型返回空值_C#_Generics_Dictionary_Null_Nullable - Fatal编程技术网

C# 为未知类型返回空值

C# 为未知类型返回空值,c#,generics,dictionary,null,nullable,C#,Generics,Dictionary,Null,Nullable,我正在尝试使用泛型编写以下方法。(我的实际方法比这更复杂。) public T ParseDictionaryItem(字符串s,字典) { T结果; if(dictionary.TryGetValue(s,out结果)) 返回结果; //TODO:返回特殊值,如null,以指示无效项 } 我的目标是,如果项目不在字典中,则返回类似于null的内容 问题是我不知道t是什么类型。例如,如果T是一个整数,那么我应该返回类型T?。但是,如果T是一个类,那么它已经可以为空。直到运行时我才知道这一点 任

我正在尝试使用泛型编写以下方法。(我的实际方法比这更复杂。)

public T ParseDictionaryItem(字符串s,字典)
{
T结果;
if(dictionary.TryGetValue(s,out结果))
返回结果;
//TODO:返回特殊值,如null,以指示无效项
}
我的目标是,如果项目不在字典中,则返回类似于
null的内容

问题是我不知道
t
是什么类型。例如,如果
T
是一个整数,那么我应该返回类型
T?
。但是,如果
T
是一个类,那么它已经可以为空。直到运行时我才知道这一点


任何人都能找到一种干净的方法来返回此方法中的特殊值,以指示该项无效吗?我愿意返回除
null
以外的内容,但它必须是一个特殊值。(0不是整数的特殊值。)

我建议返回一个
ParseResult
,它的定义如下:

public struct ParseResult<T>
{
    // Or an exception, or a way of creating an exception
    private readonly bool success;
    private readonly T value;

    // Accessors etc
}
public结构解析结果
{
//或异常,或创建异常的方法
私人只读bool成功;
私有只读T值;
//访问者等
}
这样,您就不必担心可空性,并且可以非常清楚地说明您正在做什么。这是我使用过的模式,在我看来,它非常有效。(目前我们使用的是类而不是结构,但我可能会改变这一点…)

与其他方法相比,我更喜欢它,因为:

  • 调用它是干净的,不像使用
    out
    参数
  • 它不需要丑陋且可能昂贵的try/catch处理
  • 无论
    T
    是引用类型还是值类型,其行为方式都完全相同
  • 它足够灵活,可以表示
    null
    是成功解析值的情况
  • 您仍然可以传播失败的原因,而不必在不需要时抛出异常

您可以创建两种方法,一种用于值类型,另一种用于引用类型。 值类型方法将返回
T?
,而不是
T
。在这两种方法中,都可以返回
null
以指示无效值

public T? ParseDictionaryItemValueType<T>(string s, Dictionary<string, T> dictionary)
 where T : struct
{
    T result;
    if (dictionary.TryGetValue(s, out result))
        return result;
    return null;
}

public T ParseDictionaryItemReferenceType<T>(string s, Dictionary<string, T> dictionary)
 where T : class
{
    T result;
    dictionary.TryGetValue(s, out result);
    return result;
}
公共电话?ParseDictionaryItemValueType(字符串s,字典字典) 其中T:struct { T结果; if(dictionary.TryGetValue(s,out结果)) 返回结果; 返回null; } public T ParseDictionaryItemReferenceType(字符串s,字典字典) T:在哪里上课 { T结果; TryGetValue(s,输出结果); 返回结果; }
也许两个重载会有所帮助:

public T? ParseStructDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : struct
{
    T result;
    if (dictionary.TryGetValue(s, out result))
        return result;
    return null;
}

public T ParseReferenceDictionaryItem<T>(string s, Dictionary<string, T> dictionary) where T : class
{
    T result;
    if (dictionary.TryGetValue(s, out result))
        return result;
    return default(T);
}
公共电话?ParseStructDictionaryItem(字符串s,字典字典),其中T:struct { T结果; if(dictionary.TryGetValue(s,out结果)) 返回结果; 返回null; } 公共T ParseReferenceDictionaryItem(字符串s,字典),其中T:class { T结果; if(dictionary.TryGetValue(s,out结果)) 返回结果; 返回默认值(T); }
为什么要重新发明轮子?看看您自己的代码:
您正在使用字典的
TryGetValue
方法。它如何处理同一问题?
我建议您跟随.Net Framework开发人员的脚步,也这样做:

public bool TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out T result)
{
   if (dictionary.TryGetValue(s, out result)) {
       return true;
   }
   return false;
public bool tryparsedictionary项(字符串s、字典字典、out T结果)
{
if(dictionary.TryGetValue(s,out结果)){
返回true;
}
返回false;
}

更新
既然你不喜欢这种方法,那就直接用它怎么样

public T TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out bool Success)
{
   T result = default(T);
   Success = (dictionary.TryGetValue(s, out result)) 
   return result;
}
public T tryparsedictionary项(字符串s、字典、输出成功)
{
T结果=默认值(T);
成功=(dictionary.TryGetValue(s,out结果))
返回结果;
}

最好的方法是
default(T)
,但这对于
int
来说并不是“唯一的”。最简单的方法是创建两个重载—一个用于类类型,另一个用于可空结构。或者创建您自己的
或者
键入并返回该值。为什么调用方不直接使用TryGetValue?它返回一个bool,指示该项是否有效,如果有效,则out参数包含该项。或者,如果方法更复杂,至少是遵循这种模式的东西。@mikez:正如我在问题中指出的,我的实际方法比这个更复杂。我简化了它来说明我的问题。谢谢,我正在考虑返回一个包含更多信息的类,但希望得到更轻松、更简单的内容。但这也许是最好的方法。我发现自己越来越多地使用这种模式。如果
Nullable
没有泛型参数是值类型的约束…@Jon:我能问一下,为什么在这里选择
struct
而不是类吗?@JonathanWood:很难说,没错,特别是考虑到这与野田佳彦时代的决定相反。它感觉有点像
Nullable
,实际上只是装饰了一个“真实”值。避免在每个解析操作上分配heal也很好。“当然,它也适用于类。”AnthonyPegram我知道,它们有不同的名称。对不起,我刚刚注意到了这一点。继续。是的,我看到了,但我真的不喜欢那种方法。首先,
out
参数不能是类实例属性。我觉得这更尴尬。
public T TryParseDictionaryItem<T>(string s, Dictionary<string, T> dictionary, out bool Success)
{
   T result = default(T);
   Success = (dictionary.TryGetValue(s, out result)) 
   return result;
}