开发者

Error Message: "Cannot convert type 'string?' to 'string' "

I have this code:

//Return nul开发者_如何学Gol 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;
}

I'm calling it like:

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

I get the compile error: "Error Message: "Cannot convert type 'string?' to 'string' "

How can I do effectively the idea in the code above without creating a new method?

I feel like I'm checking if it's null with the ?? operator, so, if the string is null, it will always be set to an empty string. It is handled how I expect for byte and int, why not for string?

FYI, the byteValue above, is of type byte, not byte?.


It seems you want null if it is a reference type and 0 if it is a number or similar value type. You can simply use the default keyword to get such a value from T. Also, you might want to add the this keyword to the first argument so that it can be used as an extension method.

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);
}  


T? is indicative of a Nullable<T>, which is something that is limited to structs. A string is not a struct, and therefore is not appropriate to use in a method accepting or returning T?.

Unfortunately, if you want to return null for value types as well as classes (such as string), then you would not be able to support that with a single generic method. You would need to do as Allon suggests and return default(T), which would not be null for (non-Nullable<T>) structs, or define two methods with different signatures, one for structs, and one for classes.

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") ?? ""; 


You can't have a nullable string. The type parameter of Nullable is constrained to be a value type, and String is a reference type. Your getValue method returns a nullable T- you'd need to constrain it to structs, and use a different method for classes:

//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;
}

Then

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

//This also works:
getValueObject<String>(u, "Text") ?? String.Empty;
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜