views:

96

answers:

5

we are in the process of upgrading our crappy cms system and the new assemblies have changed from int to int64. I'm running into a problem when trying to build now. I've tried casting but it doesnt seem to help. here is one excerpt of code that is causing a problem.

IDictionary<int, string> aliases 
    = new UrlAliasApi().GetUrlAliasesByType(
        Company.DataLayer.Enumeration.UrlAliasType.Recipe);
foreach (ContentBase recipe in mergedResultset)
{
   // if alias exists, overwrite quicklink!
   string alias;
   if (aliases.TryGetValue(recipe.Id, out alias))
   {
      recipe.QuickLink = alias;
   }
}

The error is

Error 323 The best overloaded method match for 'System.Collections.Generic.IDictionary.TryGetValue(int, out string)' has some invalid arguments

Its referring to recipe.Id which is an Int64 value.

Any ideas of to deal with this?

+2  A: 

Since C# is strongly typed, you can't convert like this. You need to cast the Int64 to an Int32 before you pass it in:

aliases.TryGetValue((int)recipe.Id, out alias)

Alternatively, you can change the definition of your dictionary:

IDictionary<Int64, string> aliases 
    = new UrlAliasApi().GetUrlAliasesByType(Company.DataLayer.Enumeration.UrlAliasType.Recipe)
                       .ToDictionary(kvp => (Int64)key.Key, kvp => kvp.Value);
codekaizen
The first solution is incorrect. It provides the potential for an overflow scenario to mathc an incorrect key.
JaredPar
I love this site and the great people on here. Great resource for a beginner .NET developer. Thank You codekaizen.
tking
@JaredPar - Agreed, the 2nd is safer.
codekaizen
+1  A: 

You need to cast the Int64 to an int, like this:

aliases.TryGetValue((int)recipe.Id, out alias)
SLaks
In an overflow scenario the `Id` field could be rounded down to a different valid value and produce a false positive.
JaredPar
A: 

Why can't you just use Dictionary<Int64, string> instead of Dictionary<int, string>?

Matthew Graybosch
+1  A: 

The problem here is that you are trying to use an Int64 value in a place which takes an int/Int32 type. There is no implicit conversion here and hence the compiler errors.

The best way to fix this is to convert the aliases dictionary to use an Int64 type as well. It's always safe to convert an int to Int64 so there is no information loss in this conversion.

Ideally you'd convert GetUrlAliasesByType to return an IDictionary<Int64,string>. The rest of the system is now using Int64 so this conversion makes sense. Otherwise you can do the following

string alias; 
try { 
  if (aliases.TryGetValue(checked((int)recipe.Id), out alias)) 
  { 
    recipe.QuickLink = alias; 
  } 
} catch (OverflowException) { 
  // id not valid
}

The checked operation here is necessary because it prevents a silent overflow from producing a false match with TryGetValue

JaredPar
+1  A: 

Note that while you can cast Int64 to Int32 (or int), you could lose some data if the values that you are casting are larger than can be represented in an Int32. In your case it might not matter, but I thought I should mention it.

wageoghe