Just downloaded Telerik’s JustDecompile. The installation requires you to give your email address so that was a bit disappointing but let’s see what kind of results it can produce. For these tests I used debug build (AnyCPU) of my AppSettings library (Yes, I need to give some love to that library).
Original code
public static string GetPropertyValue(
object instance,
PropertyInfo propertyInfo,
IFormatProvider formatProvider)
{
var tempValue = propertyInfo.GetValue(instance, null);
if (null == tempValue)
{
return string.Empty;
}
var value = Convert.ToString(tempValue, formatProvider);
return value;
}
JustDecompile
public static string GetPropertyValue(
object instance,
PropertyInfo propertyInfo,
IFormatProvider formatProvider)
{
string empty;
object tempValue = propertyInfo.GetValue(instance, null);
bool flag = null != tempValue;
if (flag)
{
string @value = Convert.ToString(tempValue, formatProvider);
empty = @value;
}
else
{
empty = string.Empty;
}
return empty;
}
As you can see the decompiled version is more complex. Sometimes that is normal but when you compare JustDecompile with ILSpy you get very different results.
Original code
public static bool IsConnectionString(PropertyInfo propertyInfo)
{
var attribute = propertyInfo
.GetCustomAttribute<SettingPropertyAttribute>();
return null != attribute && attribute.IsConnectionString;
}
JustDecompile
public static bool IsConnectionString(PropertyInfo propertyInfo)
{
bool isConnectionString;
SettingPropertyAttribute attribute = propertyInfo
.GetCustomAttribute<SettingPropertyAttribute>();
if (attribute == null)
{
isConnectionString = false;
}
else
{
isConnectionString = attribute.IsConnectionString;
}
bool flag = isConnectionString;
return flag;
}
ILSpy
public static bool IsConnectionString(PropertyInfo propertyInfo)
{
SettingPropertyAttribute attribute = propertyInfo
.GetCustomAttribute<SettingPropertyAttribute>();
return attribute != null && attribute.IsConnectionString;
}
How about another example of code that can be used to convert type to another type.
Original code
public static object Convert(
Type type,
string value,
IFormatProvider formatProvider)
{
// In case the type is e.g. Nullable<int>
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (string.Empty == value)
{
return (object)null;
}
// Type is nullable and we have value is not empty.
// Get the underlying type and continue the conversion.
type = Nullable.GetUnderlyingType(type);
}
if (type.IsEnum)
{
return ConvertEnum(type, value);
}
return System.Convert.ChangeType(value, type, formatProvider);
}
JustDecompile
public static object Convert(
Type type,
string value,
IFormatProvider formatProvider)
{
object obj;
bool genericTypeDefinition;
if (!type.IsGenericType)
{
genericTypeDefinition = true;
}
else
{
genericTypeDefinition = !(type.GetGenericTypeDefinition()
== typeof(Nullable`1));
}
bool empty = genericTypeDefinition;
if (!empty)
{
empty = !(string.Empty == value);
if (empty)
{
type = Nullable.GetUnderlyingType(type);
empty = !type.IsEnum;
if (empty)
{
obj = Convert.ChangeType(value,
type, formatProvider);
}
else
{
obj = TypeConverter.ConvertEnum(type, value);
}
return obj;
}
obj = null;
return obj;
}
empty = !type.IsEnum;
if (empty)
{
obj = Convert.ChangeType(value, type, formatProvider);
}
else
{
obj = TypeConverter.ConvertEnum(type, value);
}
return obj;
}
ILSpy
public static object Convert(
Type type,
string value,
IFormatProvider formatProvider)
{
object result;
if (type.IsGenericType &&
type.GetGenericTypeDefinition() == typeof(Nullable<>))
{
if (string.Empty == value)
{
result = null;
return result;
}
type = Nullable.GetUnderlyingType(type);
}
if (type.IsEnum)
{
result = TypeConverter.ConvertEnum(type, value);
}
else
{
result = Convert.ChangeType(value, type, formatProvider);
}
return result;
}
Next static method that is used to create new object
Original code
public static AppSettings CreateForAssembly(
Assembly assembly, FileOption fileOption)
{
if (null == assembly)
{
throw new ArgumentNullException("assembly",
"Cannot create AppSettings. Assembly is null.");
}
var fullPath = GetPathToConfigurationFile(assembly);
var appSettings = new AppSettings
{
Configuration = OpenConfigurationFile(fullPath, fileOption)
};
return appSettings;
}
JustDecompile
public static AppSettings CreateForAssembly(
Assembly assembly, FileOption fileOption)
{
bool flag = !(null == assembly);
if (flag)
{
string fullPath = AppSettings.GetPathToConfigurationFile(
assembly);
AppSettings appSetting = new AppSettings();
appSetting.Configuration =
AppSettings.OpenConfigurationFile(fullPath, fileOption);
AppSettings appSettings = appSetting;
AppSettings appSetting1 = appSettings;
return appSetting1;
}
else
{
throw new ArgumentNullException("assembly",
"Cannot create AppSettings. Assembly is null.");
}
}
ILSpy
public static AppSettings CreateForAssembly(
Assembly assembly, FileOption fileOption)
{
if (null == assembly)
{
throw new ArgumentNullException("assembly",
"Cannot create AppSettings. Assembly is null.");
}
string fullPath = AppSettings
.GetPathToConfigurationFile(assembly);
return new AppSettings
{
Configuration = AppSettings.OpenConfigurationFile(
fullPath, fileOption)
};
}
As you can see ILSpy produces result that is closer to the original code. That doesn’t mean JustDecompile is a bad product. It only means there is room for improvement. I’ve had really good experience using other Telerik’s products and their support has been excellent so I’m sure JustDecompile will grow to be a very good tool. Finally I hope I win the t-shirt :)