Joey Bradshaw

I'm getting this error when calling the following generic function. The registry key definately exists and the call to regKey.GetValue(keyName) does return a value of "false" in the debugger. I've tried setting the value of the registry key multiple variations such as "False", "FALSE", and "false" and still it throws the following error. Any suggestions

The error:

Cannot unbox 'regKey.GetValue(keyName)' as a 'T'

Here is the call:

bool returnValue = GetSetting("somePath", "test", false)

Here is the function itself:

public T GetSetting<T>(string formName, string keyName, T defaultValue)

{

RegistryKey regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return regKey.GetValue(keyName) == null defaultValue : (T)regKey.GetValue(keyName);

}



Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

Jose Escrich

Are you sure that's your exactly code anyway If you're receiving a "false" (an string) the default value should be an string but no a boolean, although if you're getting a dword you will receive an integer 1 for true and a 0 for false, so the default value should be an integer or you should change the internal logic for GetSetting in order to cast the dword values before to perform the return.

Remember that you can also use default(T), it depends.

hope it helps.





Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

Bashmohandes

Why don't you ToString() the output so it is the form of "False" or "false" or whatever and then use bool.Parse to get the value
also you can use this
bool x = (bool)Convert.ToBoolean(yourData);
or more generic way
T x = (T)Convert.ChangeType(yourData, typeof(T));





Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

Figo Fei - MSFT

Hi,

When you call the GetSetting<> method, you assign T as a bool type, while regKey.GetValue returns an object type.

So you cannot directly cast object type to bool type.

That's the reason.

If you the value returned just means whether it get values, what about implement in this way:

public T GetSetting<T>(string formName, string keyName, T defaultValue)

{

RegistryKey regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return regKey.GetValue(keyName) == null defaultValue : true;

}

At least, its syntax is correct.

Thanks






Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

James Curran

So you cannot directly cast object type to bool type.

Actually, you can...provided the object is a boxed bool to begin with:



object obj1 = false;
bool b1 = (bool) obj1; // OK

If it were some other type, then you'd get a run-time error:


object obj2 = 2;
bool b2 = (bool) obj2; // Error.


The object that GetValue() returns can be several different types (specifically: int, long, string, string[] or byte[]), but bool isn't among them. Most likely, the value you want is stored as an int, so it would be:



public bool GetSetting(string formName, string keyName, bool defaultValue)
{
RegistryKey regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));
object val = regKey.GetValue(keyName);
return val == null defaultValue : ((bool) ((int) val));
}

The compiler will match the non-generic before the generic, so with both, you should have every method covered.






Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

Joey Bradshaw

Sorry, it's been a while since I've had time to review this post. All of the suggestions so far defeat the purpose I'm trying to acheive. I already have 10+ overloaded functions that provide me with the functionality I need as shown below which all work perfectly. But I want to consolidate this code using one generic function so that it can handle Types I haven't yet specifically coded for yet. Make sense Is there a way to consolidate all of the following functions into one generic function without if/then/else statements If the only answer is to put if/then/else statements to identify each Type and handle the conversion manually then that obviously defeats the intent to use generics here.

public object GetSetting(string formName, string keyName, object defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : _regKey.GetValue(keyName);

}

public bool GetSetting(string formName, string keyName, bool defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : Boolean.Parse(_regKey.GetValue(keyName).ToString());

}

public string GetSetting(string formName, string keyName, string defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : _regKey.GetValue(keyName).ToString();

}

public int GetSetting(string formName, string keyName, int defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : int.Parse(_regKey.GetValue(keyName).ToString());

}

public int GetSetting(string formName, string keyName, int defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : int.Parse(_regKey.GetValue(keyName).ToString());

}

public decimal GetSetting(string formName, string keyName, decimal defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return _regKey.GetValue(keyName) == null defaultValue : decimal.Parse(_regKey.GetValue(keyName).ToString());

}





Re: Visual C# Language Cannot unbox XXXX as a 'T' - Generics

James Curran

As you own code clearly demostrates, there is no one way to convert the return value of GetValue() to the various types you want. Generics cannot magically change that fact. Essentially, overloading is the way to go, but it can be simplified a bit:

bool FromObjectOrDefault(object value, bool defaultValue)

{

return value != null : Boolean.Parse(value.ToString()) : defaultValue);
}

int FromObjectOrDefault(object value, int defaultValue)

{

return value != null : int.Parse(value.ToString()) : defaultValue);
}

/// etc...

public T GetSetting<T>(string formName, string keyName, T defaultValue)

{

_regKey = Registry.CurrentUser.CreateSubKey(GetKeyName(formName));

return FromObjectOrDefault(_regKey.GetValue(keyName));

}