Skip to content

Instantly share code, notes, and snippets.

@rubensteins
Last active December 2, 2021 09:59
Show Gist options
  • Save rubensteins/0f1cdace9207effb5ec28787644bb38e to your computer and use it in GitHub Desktop.
Save rubensteins/0f1cdace9207effb5ec28787644bb38e to your computer and use it in GitHub Desktop.
Tests performance of Reflection
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Globalization;
using System.ComponentModel;
using System.Reflection;
using System.Diagnostics;
namespace ConsoleApplication1
{
class Program
{
delegate void MethodToEvaluate(object[] parameters);
static void Main(string[] args)
{
long times = 1000000;
// creates the parameter needed for the tests
IDictionary paramAndValues = new OrderedDictionary();
paramAndValues.Add("id", "1");
paramAndValues.Add("name", "product name");
paramAndValues.Add("description", "product description");
paramAndValues.Add("price", "100");
object[] parameters = new object[]{ new Product(), paramAndValues };
// launch the test cases
EvaluateMethod("Constructor", ConstructorTest, null, times);
EvaluateMethod("Constructor using reflection", ConstructorTestReflection, null, times);
EvaluateMethod("Method call", MethodCall, null, times);
EvaluateMethod("Method call using reflection", MethodCallReflection, null, times);
EvaluateMethod("Setting properties", SetProperties, parameters, times);
EvaluateMethod("Setting properties using reflection", SetPropertiesReflection, parameters, times);
Console.ReadLine();
}
// evaluates a method the specified number of times and print performance information
static void EvaluateMethod(string testName, MethodToEvaluate method, object[] parameters, long times)
{
Console.WriteLine(testName);
Stopwatch timer = new Stopwatch();
timer.Start();
for (long i = 0; i < times; i++) {
method(parameters);
}
timer.Stop();
Console.WriteLine($"Time elapsed (ms): {timer.ElapsedMilliseconds} which is {timer.ElapsedTicks} ticks for {times} calls.\n");
}
static void ConstructorTest(object[] parameters)
{
Product prod = new Product();
}
static void ConstructorTestReflection(object[] parameters)
{
Activator.CreateInstance(typeof(Product));
}
static void MethodCall(object[] parameters)
{
Product.TestMethod(0, "test");
}
static void MethodCallReflection(object[] parameters)
{
MethodInfo method = typeof(Product).GetMethod("TestMethod", BindingFlags.Public | BindingFlags.Static);
object[] paramValues = new object[]{ 0, "test" };
method.Invoke(null, paramValues);
}
static void SetProperties(object[] parameters)
{
Product prod = (Product)parameters[0];
IDictionary values = (IDictionary)parameters[1];
prod.Id = Convert.ToInt32(values["id"]);
prod.Name = (string)values["name"];
prod.Description = (string)values["description"];
prod.Price = Convert.ToDecimal(values["price"]);
}
static void SetPropertiesReflection(object[] parameters)
{
Product prod = (Product)parameters[0];
IDictionary values = (IDictionary)parameters[1];
SetProperty(prod, "Id", values["Id"]);
SetProperty(prod, "Name", values["name"]);
SetProperty(prod, "Description", values["description"]);
SetProperty(prod, "Price", values["price"]);
}
#region Helper Methods
static void SetProperty(object obj, string name, object value)
{
// searchs for the property
PropertyInfo prop = typeof(Product).GetProperty(name);
// try to convert a string value to an object (using the type converter)
object propertyValue = BuildObjectValue(value, prop.PropertyType);
// sets the property value
prop.SetValue(obj, propertyValue, null);
}
static object BuildObjectValue(object value, Type destinationType)
{
// if we have a value that needs conversion
if ((value != null) && !destinationType.IsInstanceOfType(value)) {
Type targetType = destinationType;
// if the value is a string, try to convert it to the target type
if (value is string) {
value = ConvertStringToType((string)value, targetType);
}
}
return value;
}
static object ConvertStringToType(string value, Type destinationType)
{
object result = null;
// try to get a type converter
TypeConverter converter = TypeDescriptor.GetConverter(destinationType);
if (converter == null) {
return value;
}
// try to convert the string using the type converter
result = converter.ConvertFromString(null, CultureInfo.CurrentCulture, value);
return result;
}
#endregion
}
class Product
{
public int Id { get; set; }
public string? Name { get; set; }
public string? Description { get; set; }
public decimal Price { get; set; }
public static void TestMethod(int id, string value)
{
}
}
}
@rubensteins
Copy link
Author

This code was converted from a snippet from 2006 (https://web.archive.org/web/20201019153235/http://www.manuelabadia.com/blog/PermaLink,guid,772c7152-b00e-4334-b677-bfbdcd8e6b5d.aspx). I added a Product-class and removed references to ProductDal (instead gave Product a static method to call). The code compiles and runs fine with dot net 6, but gives a few null-related warnings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment