2011-10-07 106 views
1

我有这样的代码:错误消息:“无法转换类型'字符串?'以“串”“

//Return null if the extension doesn't have the value, returns the value if it does. 
private T? getValue<T>(IEnumerable<Extension> extension, string attributeName) 
{ 
    IEnumerable<Extension> ext = extension.Where(e => e.attributeName == attributeName); 
    if (ext.Count() > 0) 
    { 
     return (T)ext.First().Attribute; 
    } 
    return null; 
} 

我打电话是这样的:

//This works: 
retVal.byteValue= getValueFromExtension<byte>(u, "ByteToGet") ?? 0; 
//This doesn't work: 
getValueFromExtension<string>(u, "Text") ?? ""; 

我得到的编译错误:”错误消息:“无法将类型“字符串? “以“串”“

我怎样才能有效地做好代码的理念之上,而无需创建一个新的方法?

我觉得我检查,如果它是空与??运营商,因此,如果字符串为空,它将总是被设置为一个空字符串,它是如何处理字节和整数,为什么不是字符串?

上面的字节值,是字节类型,不是字节?

+2

这段代码编译过的?我很困惑'T?'方法的返回类型 – sll

+2

什么是'getValueFromExtension'? – Oded

+4

我不明白为什么你的方法甚至编译没有'struct'约束。 – CodesInChaos

回答

6

看来你想null如果是引用类型和0,如果它是一个数字或类似的值类型。您可以简单地使用default关键字从T获取此类值。另外,您可能需要将this关键字添加到第一个参数,以便它可以用作扩展方法。

private T getValue<T>(this IEnumerable<Extension> extension, string attributeName) 
{ 
    Extension ext = extension.SingleOrDefault(e => e.attributeName == attributeName); 

    if (ext != null) 
     return (T)ext.Attribute; 
    else 
     return default(T); 
} 
+1

如果你需要值类型的自定义默认值,你仍然可以使用类似的东西(注意“** byte?**”): retVal.byteValue = getValueFromExtension (u,“ByteToGet”)? 42;但在这种情况下,将默认值传递给getValue方法作为更多参数更合理 – SergGr

+0

@SergGr:非常好,没有想到这一点。我只能想到为这种方法增加另一个重载。 –

+0

StackOverflow非常棒,每个答案都在这里帮助我,花了大约5分钟才得到完整的答案。多谢你们。 – Dale

3

T?表示Nullable<T>,这是一个限于结构的东西。字符串不是结构体,因此不适用于接受或返回T?的方法。

不幸的是,如果你想返回null值类型以及类(如字符串),那么你就不能支持用一个通用的方法。您需要按照Allon的建议并返回default(T),这将而不是为null(非Nullable<T>)结构为空,或者定义两个方法具有不同签名,一个用于结构,一个用于类。

private T getValueForClass<T>(IEnumerable<Extension> extension, string attributeName) 
    where T : class 

private T? getValueForStruct<T>(IEnumerable<Extension> extension, string attributeName) 
    where T : struct 

... 

var theByte = getValueForStruct<byte>(extensions, "ByteToGet") ?? 0; 
var theString = getValueForClass<string>(extensions, "Text") ?? ""; 
+0

有道理,谢谢。我没有想过这个。 – Dale

+0

你的回答很好,我只能接受其中之一作为答案,所以我接受了其他实际使用的内容。 – Dale

+0

@ user788402,很好!始终接受对您有用的人。投币翻转也是可以接受的。 –

2

您不能有空字符串。 Nullable的类型参数被约束为一个值类型,而String是一个引用类型。你getValue方法返回一个可为空T-你需要将其约束到结构,并使用不同的方法类:

//Return null if the extension doesn't have the value, returns the value if it does. 
private T? getValue<T>(IEnumerable<Extension> extension, string attributeName) where T : struct 
{ 
    IEnumerable<Extension> ext = extension.Where(e => e.attributeName == attributeName); 
    if (ext.Count() > 0) 
    { 
     return (T)ext.First().Attribute; 
    } 
    return null; 
} 

//Return null if the extension doesn't have the value, returns the value if it does. 
private T getValueObject<T>(IEnumerable<Extension> extension, string attributeName) where T : class 
{ 
    IEnumerable<Extension> ext = extension.Where(e => e.attributeName == attributeName); 
    if (ext.Count() > 0) 
    { 
     return (T)ext.First().Attribute; 
    } 
    return null; 
} 

然后

//This works: 
getValue<Byte>(u, "ByteToGet") ?? 0; 

//This also works: 
getValueObject<String>(u, "Text") ?? String.Empty; 
相关问题