calling an overloaded method in generic method - c#

class Test
{
public BinaryWriter Content { get; private set; }
public Test Write<T> (T data)
{
Content.Write(data);
return this;
}
}
it won't compile.
1. The best overloaded method match for 'System.IO.BinaryWriter.Write(bool)' has some invalid arguments
2. Argument 1: cannot convert from 'T' to 'bool'
it seems like Test.Write is always trying to call BinaryWriter.Write(bool). any suggestions?

Overload resolution happens at compile-time, and in this case nothing is known about T, so no overload is applicable.
class Test
{
public BinaryWriter Content { get; private set; }
public Test Write<T>(T data)
{
Content.Write((dynamic)data);
return this;
}
}
But of course it could make some problems. For example, appliction will compile fine, if you will send DateTime to the method. But, it will throw exception.

This is possible but not with generic constraints . You can try to use Reflection and get the appropriate overloaded version of Write method according to type of T.
Initialize your BinaryWriter with a Stream in your constructor then use Reflection like below:
class Test
{
public BinaryWriter Content { get; private set; }
public Test(Stream stream)
{
Content = new BinaryWriter(stream);
}
public Test Write<T>(T data)
{
var method = typeof (BinaryWriter).GetMethod("Write", new[] {data.GetType()});
if (method != null)
{
method.Invoke(Content, new object[] { data });
}
// here you might want to throw an exception if method is not found
return this;
}
}
Here is a test program:
Test writer;
using (var fs = new FileStream("sample.txt", FileMode.Open))
{
writer = new Test(fs);
writer = writer.Write(232323);
writer = writer.Write(true);
writer = writer.Write(12);
}
using (var fs = File.Open("sample.txt", FileMode.Open))
{
var reader = new BinaryReader(fs);
Console.WriteLine(reader.ReadInt32()); // 232323
Console.WriteLine(reader.ReadBoolean()); // true
Console.WriteLine(reader.ReadByte()); // 12
}

In your write method T is generic, which means that T can be anything, but BinaryWriter.Write doesn't takes a generic overload. So you can't do that.

You can't do that.
Since real type of T is unknown at compile-time, compiler can't find appropriate Write overload, and tries to call the first found one. There is no overload, which could be called with any type of T (e.g., Write(object)).

Using Reflection considerably slows down method calls. It also moves argument type check from compile time to runtime, which is undesirable in most cases.
Using dynamic calls in this case is just a fancy and slightly optimized version of the previous method which has the same drawbacks.
The correct way is to copy all overloads:
public Test Write (bool data)
{
Content.Write(data);
return this;
}
public Test Write (byte data)
{
Content.Write(data);
return this;
}
public Test Write (byte[] data)
{
Content.Write(data);
return this;
}
public Test Write (char data)
{
Content.Write(data);
return this;
}
public Test Write (char[] data)
{
Content.Write(data);
return this;
}
// ...
This method is very verbose, but it is the only that provides compile-time checks of arument types and is the most performant as it chooses overloads and compile-time. Furthermore, these methods are likely to be inlined.
In cases like this, I usually use a T4 script which generates code like above based on Reflection. Create a TT file, enumerate Write overloads of BinaryWriter, generate code.

Related

C# Generic Deserializer by calling static methods

I am deserializing lots of data with the Newtonsoft Json.NET library. Performance is high-priority, so all model classes are being manually deserialized with a JsonReader. Each model class has its own static constructor method FromJson which accepts a JsonReader to do the reading.
class Example
{
public Guid? Id { get; private set; }
public DateTime? Date { get; private set; }
public decimal? Amount { get; private set; }
public static Example FromJson(JsonReader reader)
{
var example = new Example();
reader.SkipToStartObject(); // Extension method, skips to first JsonToken.StartObject
while(reader.Read() && reader.TokenType == JsonToken.PropertyName)
{
var propertyName = reader.Value.ToString();
switch(propertyName)
{
case "id":
example.Id = reader.ReadAsGuid(); // Extension method
break;
case "date":
example.Date = reader.ReadAsDateTime();
break;
case "amount":
example.Amount = reader.ReadAsDecimal();
break;
default:
break;
}
}
return example;
}
}
I would like to somehow interface this class so that I can write a generic deserializer that takes that interface and automatically calls the FromJson() method. Ideally, I would be able to cleanly deserialize a WebResponse in a manner like so.
var response = await request.GetResponseAsync();
var stream = response.GetResponseStream();
return GenericJsonDeserializer.Deserialize<Example>(stream);
The GenericJsonDeserializer would constrain the allowed types to only those with the interface, set up a JsonReader from the stream, deserialize with the FromJson method, and return the object.
One problem is that C# interfaces don't allow required constructors, nor do they allow static methods. Thus, I cannot constrain GenericJsonSerializer.
This problem is solvable with reflection, but that brings about a new problem. Performance is critical, and I cannot afford to use reflection in this case. Creating a new instance inside of the generic method would either:
Require the use of Activator if the deserialization code was handled in a regular constructor, or
Require reflection to obtain the static FromJson function and invoke it, which is probably even slower.
In either case, compiling DynamicMethods by emitting IL would be a best bet (and probably offer the best performance), but I would like to avoid that scenario if possible.
Is there any other way I can constrain a generic method to require either a static constructor or a constructor overload that accepts a JsonReader for deserialization?
Instead of constraining the ctor, you can constrain to an initialize method:
the self referencing constraint is not really necessary
public interface IDeserializable<T> where T : IDeserializable<T>, new()
{
T FromJson(JsonReader reader);
}
Then modify Example to implement that interface:
public class Example : IDeserializable<Example>
{
//...
public Example FromJson(JsonReader reader)
{
// populate the object with json...
// you can create complex object like this:
// this.Example2 = new Example2().FromJson(reader);
return this;
}
}
Finally, define the Deserialize method as such:
public static class GenericJsonSerializer
{
public static T Deserialize<T>(Stream steam) where T : IDeserializable<T>, new()
{
using (var reader = ...)
{
var result = new T();
result.FromJson(reader);
return result;
}
}
}
Since you're using here the type 'Example':
GenericJsonDeserializer.Deserialize<Example>(stream);
You can just use:
Example.FromJson
Beacause you need to know the type anyway.
Just make a version that accepts Stream and JsonReader or whatever.
You can share the logic for creating JsonReader by some other static class if you need to.
There is also another approach. You can move / extract your FromJson method to another class / interface:
interface IMyJsonDeserializer
{
void FromJson(Stream stream, out ExampleClassA result);
void FromJson(Stream stream, out ExampleClassB result);
}
class MyJsonDeserializer : IMyJsonDeserializer
{
public void FromJson(Stream stream, out ExampleClassA result)
{
// code to deserialize
}
public void FromJson(Stream stream, out ExampleClassB result)
{
// code to deserialize
}
// .. more methods
}
Usage:
var deserializer = new MyJsonDeserializer(); // you can create it just once somewhere
ExampleClassA a;
deserializer.FromJson(stream, out a);
ExampleClassB b;
deserializer.FromJson(stream, out b);
If you have a lot of classes you can do some interface segregation and inheritance. You can now share your logic for creating JsonReader from Stream using OOP methods.
If you do care about perfrormance you can take a look at Utf8Json. It is proved to be faster than Newtonsoft.Json

How to use generics to pass argument to a non-generic method?

Why does the following code not compile?
How can I create a generic method which calls the appropriate "BitConverter.GetBytes" overload based on if the generic type is an "int", "bool", "char", etc.?
More generally, how can I create a generic method which calls a non-generic method based on the generic parameter's type?
using System;
public class Test
{
public static void Main()
{
var f = new Foo();
f.GetBytes(10); // should call BitConverter.GetBytes(int);
f.GetBytes(true); // should call BitConverter.GetBytes(bool);
f.GetBytes('A'); // should call BitConverter.GetBytes(char);
}
}
public class Foo
{
public byte[] GetBytes <TSource> (TSource input)
{
BitConverter.GetBytes(input);
}
}
More generally, how can I create a generic method which calls a non-generic method based on the generic parameter's type?
In general, you can't, unless the method in question takes System.Object as a parameter. The problem is that the generic isn't constrained to just types that would be allowed by the method call arguments.
The closest you can do is to use runtime binding:
public byte[] GetBytes <TSource> (TSource input)
{
dynamic obj = input;
BitConverter.GetBytes(obj);
}
This pushes the method binding logic to runtime, and will throw if there isn't an appropriate method to call.
The reason this doesn't work is that generic methods still resolve calls to methods made within them statically. Since TSource could be any type at all, it can only call a method on BitConverter which takes an object argument. Since none exists, the compilation fails.
The only way to get the behaviour you want to is to use dynamic:
public byte[] GetBytes <TSource> (TSource input)
{
BitConverter.GetBytes((dynamic)input);
}
although the generic parameter is now redundant and you have no type safety.
In this situation you can either create a number of matching overloads e.g.
public byte[] GetBytes(bool b) { ... }
public byte[] GetBytes(int i) { ... }
or take a Func<T, byte[]> argument and wrap each BitConverter method you need e.g.
public void DoSomething<T>(T input, Func<T, byte[]> f)
{
byte[] bytes = f(input);
//handle bytes
}
DoSomething(true, BitConverter.GetBytes);
which may give you more flexibility.
Where the code is calling BitConverter.GetBytes, the type is TSource, so the call can't be statically bound by the compiler. You can work around this using dynamic invocation, meaning it'll compile fine and then get resolved at runtime:
…
public byte[] GetBytes(dynamic input)
{
return BitConverter.GetBytes(input);
}
You will pay a performance penalty for using dynamic invocation and if no suitable method to call is available you will get a runtime exception.
Given that there are "only" 10 overloads of BitConverter.GetBytes, it's not impossible to reflect them all explicitly like this:
public class Foo
{
public byte[] GetBytes(bool input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(char input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(double input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(float input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(int input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(short input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(long input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(uint input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(ulong input) { return BitConverter.GetBytes(input); }
public byte[] GetBytes(ushort input) { return BitConverter.GetBytes(input); }
}
It's not generic (which you had asked for), and isn't scalable to more complex examples, but if the numbers are small then it's an approach to consider.
If you are willing to take a performance hit, you can use reflection and an extension to object called GetBytes. example....
public static class Extensions
{
#region Fields
public static Type bcType;
#endregion
#region Constructor
static Extensions()
{
bcType = typeof(BitConverter);
}
#endregion
public static byte[] GetBytes(this object value)
{
Type typeObj = value.GetType();
MethodInfo miGetBytes = bcType.GetMethod("GetBytes", new Type[] { typeObj });
if (miGetBytes == null)
throw new InvalidOperationException("Method: GetBytes on BitConverter does not have an overload accepting one paramter of type: " + typeObj.FullName);
byte[] bytesRet = (byte[])miGetBytes.Invoke(null, new object[] { obj });
return bytesRet;
}
}
So GetBytes accepts an object. Then it get's it's type and tries to get the MethodInfo from BitConverter based on the type of object passed in. If it can't find an overload that accepts that type as a parameter it throws an InvalidOperation Exception. If it does, it calls it passing in the instance of obj as the value and returns the byte array.
E.g. Usage code,
//make sure the extensions namespace is defined where this code is run.
Console.WriteLine(((ushort)255).GetBytes().ToBase64());
Console.WriteLine(10.0.GetBytes().ToBase64());
Console.WriteLine(((int)2000000000).GetBytes().ToBase64());
Console.WriteLine(((short)128).GetBytes().ToBase64());
//Below causes an error
Console.WriteLine("cool".GetBytes().ToBase64()); //because BitConvert.GetBytes has no overload accepting an argument of type string.
You'll need to use reflection to do that.
Get the GetBytes method group from the BitConverter static type.
Pull out the overload for which the first parameter has type TSource.
Call that specific method via the Invoke method.
If you aren't familiar with some of this, I can expand the answer with code for those steps.
Edit: Or just use dynamic like others are suggesting and save yourself some work.
Your code doesn't compile because the compiler can't verify that any type for TSource will be accepted by BitConverter.GetBytes(). You can check for each type individually and cast:
public byte[] GetBytes <TSource> (TSource input)
{
var t = typeof(TSource);
return (t == typeof(int)) ? BitConverter.GetBytes((int) (object) input)
: (t == typeof(bool)) ? BitConverter.GetBytes((bool)(object) input)
: (t == typeof(char)) ? BitConverter.GetBytes((char)(object) input)
: null;
}

C# Using Activator.CreateInstance

I asked a question yesterday regarding using either reflection or Strategy Pattern for dynamically calling methods.
However, since then I have decided to change the methods into individual classes that implement a common interface. The reason being, each class, whilst bearing some similarities also perform certain methods unique to that class.
I had been using a strategy as such:
switch (method)
{
case "Pivot":
return new Pivot(originalData);
case "GroupBy":
return new GroupBy(originalData);
case "Standard deviation":
return new StandardDeviation(originalData);
case "% phospho PRAS Protein":
return new PhosphoPRASPercentage(originalData);
case "AveragePPPperTreatment":
return new AveragePPPperTreatment(originalData);
case "AvgPPPNControl":
return new AvgPPPNControl(originalData);
case "PercentageInhibition":
return new PercentageInhibition(originalData);
default:
throw new Exception("ERROR: Method " + method + " does not exist.");
}
However, as the number of potential classes grow, I will need to keep adding new ones, thus breaking the closed for modification rule.
Instead, I have used a solution as such:
var test = Activator.CreateInstance(null, "MBDDXDataViews."+ _class);
ICalculation instance = (ICalculation)test.Unwrap();
return instance;
Effectively, the _class parameter is the name of the class passed in at runtime.
Is this a common way to do this, will there be any performance issues with this?
I am fairly new to reflection, so your advice would be welcome.
When using reflection you should ask yourself a couple of questions first, because you may end up in an over-the-top complex solution that's hard to maintain:
Is there a way to solve the problem using genericity or class/interface inheritance?
Can I solve the problem using dynamic invocations (only .NET 4.0 and above)?
Is performance important, i.e. will my reflected method or instantiation call be called once, twice or a million times?
Can I combine technologies to get to a smart but workable/understandable solution?
Am I ok with losing compile time type safety?
Genericity / dynamic
From your description I assume you do not know the types at compile time, you only know they share the interface ICalculation. If this is correct, then number (1) and (2) above are likely not possible in your scenario.
Performance
This is an important question to ask. The overhead of using reflection can impede a more than 400-fold penalty: that slows down even a moderate amount of calls.
The resolution is relatively easy: instead of using Activator.CreateInstance, use a factory method (you already have that), look up the MethodInfo create a delegate, cache it and use the delegate from then on. This yields only a penalty on the first invocation, subsequent invocations have near-native performance.
Combine technologies
A lot is possible here, but I'd really need to know more of your situation to assist in this direction. Often, I end up combining dynamic with generics, with cached reflection. When using information hiding (as is normal in OOP), you may end up with a fast, stable and still well-extensible solution.
Losing compile time type safety
Of the five questions, this is perhaps the most important one to worry about. It is very important to create your own exceptions that give clear information about reflection mistakes. That means: every call to a method, constructor or property based on an input string or otherwise unchecked information must be wrapped in a try/catch. Catch only specific exceptions (as always, I mean: never catch Exception itself).
Focus on TargetException (method does not exist), TargetInvocationException (method exists, but rose an exc. when invoked), TargetParameterCountException, MethodAccessException (not the right privileges, happens a lot in ASP.NET), InvalidOperationException (happens with generic types). You don't always need to try to catch all of them, it depends on the expected input and expected target objects.
To sum it up
Get rid of your Activator.CreateInstance and use MethodInfo to find the factory-create method, and use Delegate.CreateDelegate to create and cache the delegate. Simply store it in a static Dictionary where the key is equal to the class-string in your example code. Below is a quick but not-so-dirty way of doing this safely and without losing too much type safety.
Sample code
public class TestDynamicFactory
{
// static storage
private static Dictionary<string, Func<ICalculate>> InstanceCreateCache = new Dictionary<string, Func<ICalculate>>();
// how to invoke it
static int Main()
{
// invoke it, this is lightning fast and the first-time cache will be arranged
// also, no need to give the full method anymore, just the classname, as we
// use an interface for the rest. Almost full type safety!
ICalculate instanceOfCalculator = this.CreateCachableICalculate("RandomNumber");
int result = instanceOfCalculator.ExecuteCalculation();
}
// searches for the class, initiates it (calls factory method) and returns the instance
// TODO: add a lot of error handling!
ICalculate CreateCachableICalculate(string className)
{
if(!InstanceCreateCache.ContainsKey(className))
{
// get the type (several ways exist, this is an eays one)
Type type = TypeDelegator.GetType("TestDynamicFactory." + className);
// NOTE: this can be tempting, but do NOT use the following, because you cannot
// create a delegate from a ctor and will loose many performance benefits
//ConstructorInfo constructorInfo = type.GetConstructor(Type.EmptyTypes);
// works with public instance/static methods
MethodInfo mi = type.GetMethod("Create");
// the "magic", turn it into a delegate
var createInstanceDelegate = (Func<ICalculate>) Delegate.CreateDelegate(typeof (Func<ICalculate>), mi);
// store for future reference
InstanceCreateCache.Add(className, createInstanceDelegate);
}
return InstanceCreateCache[className].Invoke();
}
}
// example of your ICalculate interface
public interface ICalculate
{
void Initialize();
int ExecuteCalculation();
}
// example of an ICalculate class
public class RandomNumber : ICalculate
{
private static Random _random;
public static RandomNumber Create()
{
var random = new RandomNumber();
random.Initialize();
return random;
}
public void Initialize()
{
_random = new Random(DateTime.Now.Millisecond);
}
public int ExecuteCalculation()
{
return _random.Next();
}
}
I suggest you give your factory implementation a method RegisterImplementation. So every new class is just a call to that method and you are not changing your factories code.
UPDATE:
What I mean is something like this:
Create an interface that defines a calculation. According to your code, you already did this. For the sake of being complete, I am going to use the following interface in the rest of my answer:
public interface ICalculation
{
void Initialize(string originalData);
void DoWork();
}
Your factory will look something like this:
public class CalculationFactory
{
private readonly Dictionary<string, Func<string, ICalculation>> _calculations =
new Dictionary<string, Func<string, ICalculation>>();
public void RegisterCalculation<T>(string method)
where T : ICalculation, new()
{
_calculations.Add(method, originalData =>
{
var calculation = new T();
calculation.Initialize(originalData);
return calculation;
});
}
public ICalculation CreateInstance(string method, string originalData)
{
return _calculations[method](originalData);
}
}
This simple factory class is lacking error checking for the reason of simplicity.
UPDATE 2:
You would initialize it like this somewhere in your applications initialization routine:
CalculationFactory _factory = new CalculationFactory();
public void RegisterCalculations()
{
_factory.RegisterCalculation<Pivot>("Pivot");
_factory.RegisterCalculation<GroupBy>("GroupBy");
_factory.RegisterCalculation<StandardDeviation>("Standard deviation");
_factory.RegisterCalculation<PhosphoPRASPercentage>("% phospho PRAS Protein");
_factory.RegisterCalculation<AveragePPPperTreatment>("AveragePPPperTreatment");
_factory.RegisterCalculation<AvgPPPNControl>("AvgPPPNControl");
_factory.RegisterCalculation<PercentageInhibition>("PercentageInhibition");
}
Just as an example how to add initialization in the constructor:
Something similar to: Activator.CreateInstance(Type.GetType("ConsoleApplication1.Operation1"), initializationData);
but written with Linq Expression, part of code is taken here:
public class Operation1
{
public Operation1(object data)
{
}
}
public class Operation2
{
public Operation2(object data)
{
}
}
public class ActivatorsStorage
{
public delegate object ObjectActivator(params object[] args);
private readonly Dictionary<string, ObjectActivator> activators = new Dictionary<string,ObjectActivator>();
private ObjectActivator CreateActivator(ConstructorInfo ctor)
{
Type type = ctor.DeclaringType;
ParameterInfo[] paramsInfo = ctor.GetParameters();
ParameterExpression param = Expression.Parameter(typeof(object[]), "args");
Expression[] argsExp = new Expression[paramsInfo.Length];
for (int i = 0; i < paramsInfo.Length; i++)
{
Expression index = Expression.Constant(i);
Type paramType = paramsInfo[i].ParameterType;
Expression paramAccessorExp = Expression.ArrayIndex(param, index);
Expression paramCastExp = Expression.Convert(paramAccessorExp, paramType);
argsExp[i] = paramCastExp;
}
NewExpression newExp = Expression.New(ctor, argsExp);
LambdaExpression lambda = Expression.Lambda(typeof(ObjectActivator), newExp, param);
return (ObjectActivator)lambda.Compile();
}
private ObjectActivator CreateActivator(string className)
{
Type type = Type.GetType(className);
if (type == null)
throw new ArgumentException("Incorrect class name", "className");
// Get contructor with one parameter
ConstructorInfo ctor = type.GetConstructors()
.SingleOrDefault(w => w.GetParameters().Length == 1
&& w.GetParameters()[0].ParameterType == typeof(object));
if (ctor == null)
throw new Exception("There is no any constructor with 1 object parameter.");
return CreateActivator(ctor);
}
public ObjectActivator GetActivator(string className)
{
ObjectActivator activator;
if (activators.TryGetValue(className, out activator))
{
return activator;
}
activator = CreateActivator(className);
activators[className] = activator;
return activator;
}
}
The usage is following:
ActivatorsStorage ast = new ActivatorsStorage();
var a = ast.GetActivator("ConsoleApplication1.Operation1")(initializationData);
var b = ast.GetActivator("ConsoleApplication1.Operation2")(initializationData);
The same can be implemented with DynamicMethods.
Also, the classes are not required to be inherited from the same interface or base class.
Thanks, Vitaliy
One strategy that I use in cases like this is to flag my various implementations with a special attribute to indicate its key, and scan the active assemblies for types with that key:
[AttributeUsage(AttributeTargets.Class)]
public class OperationAttribute : System.Attribute
{
public OperationAttribute(string opKey)
{
_opKey = opKey;
}
private string _opKey;
public string OpKey {get {return _opKey;}}
}
[Operation("Standard deviation")]
public class StandardDeviation : IOperation
{
public void Initialize(object originalData)
{
//...
}
}
public interface IOperation
{
void Initialize(object originalData);
}
public class OperationFactory
{
static OperationFactory()
{
_opTypesByKey =
(from a in AppDomain.CurrentDomain.GetAssemblies()
from t in a.GetTypes()
let att = t.GetCustomAttributes(typeof(OperationAttribute), false).FirstOrDefault()
where att != null
select new { ((OperationAttribute)att).OpKey, t})
.ToDictionary(e => e.OpKey, e => e.t);
}
private static IDictionary<string, Type> _opTypesByKey;
public IOperation GetOperation(string opKey, object originalData)
{
var op = (IOperation)Activator.CreateInstance(_opTypesByKey[opKey]);
op.Initialize(originalData);
return op;
}
}
That way, just by creating a new class with a new key string, you can automatically "plug in" to the factory, without having to modify the factory code at all.
You'll also notice that rather than depending on each implementation to provide a specific constructor, I've created an Initialize method on the interface I expect the classes to implement. As long as they implement the interface, I'll be able to send the "originalData" to them without any reflection weirdness.
I'd also suggest using a dependency injection framework like Ninject instead of using Activator.CreateInstance. That way, your operation implementations can use constructor injection for their various dependencies.
Essentially, it sounds like you want the factory pattern. In this situation, you define a mapping of input to output types and then instantiate the type at runtime like you are doing.
Example:
You have X number of classes, and they all share a common interface of IDoSomething.
public interface IDoSomething
{
void DoSomething();
}
public class Foo : IDoSomething
{
public void DoSomething()
{
// Does Something specific to Foo
}
}
public class Bar : IDoSomething
{
public void DoSomething()
{
// Does something specific to Bar
}
}
public class MyClassFactory
{
private static Dictionary<string, Type> _mapping = new Dictionary<string, Type>();
static MyClassFactory()
{
_mapping.Add("Foo", typeof(Foo));
_mapping.Add("Bar", typeof(Bar));
}
public static void AddMapping(string query, Type concreteType)
{
// Omitting key checking code, etc. Basically, you can register new types at runtime as well.
_mapping.Add(query, concreteType);
}
public IDoSomething GetMySomething(string desiredThing)
{
if(!_mapping.ContainsKey(desiredThing))
throw new ApplicationException("No mapping is defined for: " + desiredThing);
return Activator.CreateInstance(_mapping[desiredThing]) as IDoSomething;
}
}
There's no error checking here. Are you absolutely sure that _class will resolve to a valid class? Are you controlling all the possible values or does this string somehow get populated by an end-user?
Reflection is generally most costly than avoiding it. Performance issues are proportionate to the number of objects you plan to instantiate this way.
Before you run off and use a dependency injection framework read the criticisms of it. =)

Code Analysis Warning CA1004 with generic method

I have the following generic method:
// Load an object from the disk
public static T DeserializeObject<T>(String filename) where T : class
{
XmlSerializer xmlSerializer = new XmlSerializer(typeof(T));
try
{
TextReader textReader = new StreamReader(filename);
var result = (T)xmlSerializer.Deserialize(textReader);
textReader.Close();
return result;
}
catch (FileNotFoundException)
{ }
return null;
}
When I compile I get the following warning:
CA1004 : Microsoft.Design : Consider a design where 'MiscHelpers.DeserializeObject(string)' doesn't require explicit type parameter 'T' in any call to it.
I have considered this and I don't know a way to do what it requests with out limiting the types that can be deserialized. I freely admit that I might be missing an easy way to fix this.
But if I am not, then is my only recourse to suppress this warning? I have a clean project with no warnings or messages. I would like to keep it that way.
I guess I am asking "why this is a warning?" At best this seems like it should be a message. And even that seems a bit much. Either it can or it can't be fixed. If it can't then you are just stuck with the warning with no recourse but suppressing it. Am I wrong?
Since you're using T in the return type, this is a false positive.
It was fixed in Code Analysis for VS2010.
This is a fair usage warning. The trouble is that the compiler cannot deduce the type argument from the method call. The left side of the assignment statement is not considered. For example:
class Example {
public T Method1<T>() {
return default(T);
}
public T Method2<T>(T arg) {
return arg;
}
public void Test() {
int value1 = Method1(); // CS0411
int value2 = Method1<int>(); // OK
int value3 = Method2(42); // Inferred, no problems
}
}
Note how Method1 must be called by explicitly specifying the type argument. That's okay but makes it harder to use the method. That's why CA1002 is a usage warning. Method2 doesn't have this problem, the compiler can automatically infer that the type argument must be an integer from the argument type.
Two possible ways you could apply this to your method:
public static void DeserializeObject<T>(String filename, out T result) where T : class {
// etc..
}
or
public static T DeserializeObject<T>(String filename, T defaultValue) where T : class {
// etc...
}
Not so sure these are better solutions, although swallowing exceptions and returning null doesn't win prizes either. It is up to you to make the call.

Better Alternative to Case Statement

I currently have a switch statement that runs around 300 odd lines. I know this is not as giant as it can get, but I'm sure there's a better way to handle this.
The switch statement takes an Enum that is used to determine certain properties that pertain to logging. Right now the problem sets in that it is very easy to leave out an enumeration value and that it will not be given a value as it is not in the switch statement.
Is there an option one can use to ensure that every enumeration is used and given a custom set of values it needs to do its job?
EDIT:
Code sample as requested: (This is simplistic, but shows exactly what I mean. Also an Enumeration would exist with the below values.)
internal void GenerateStatusLog(LogAction ActionToLog)
{
switch (ActionToLog)
{
case LogAction.None:
{
return;
}
case LogAction.LogThis:
{
ActionText = "Logging this Information";
LogText = "Go for it.";
break;
}
}
// .. Do everything else
}
EDIT
I thought this over again, looked around in related questions in SO, and I wrote some code. I created a class named AdvancedSwitch<T>, which allows you to add cases and exposes a method to evaluate a value and lets you specify values that it should check for existence.
This is what I came up with:
public class AdvancedSwitch<T> where T : struct
{
protected Dictionary<T, Action> handlers = new Dictionary<T, Action>();
public void AddHandler(T caseValue, Action action)
{
handlers.Add(caseValue, action);
}
public void RemoveHandler(T caseValue)
{
handlers.Remove(caseValue);
}
public void ExecuteHandler(T actualValue)
{
ExecuteHandler(actualValue, Enumerable.Empty<T>());
}
public void ExecuteHandler(T actualValue, IEnumerable<T> ensureExistence)
{
foreach (var val in ensureExistence)
if (!handlers.ContainsKey(val))
throw new InvalidOperationException("The case " + val.ToString() + " is not handled.");
handlers[actualValue]();
}
}
You can consume the class this way:
public enum TrafficColor { Red, Yellow, Green }
public static void Main()
{
Console.WriteLine("Choose a traffic color: red, yellow, green?");
var color = (TrafficColor)Enum.Parse(typeof(TrafficColor), Console.ReadLine());
var result = string.Empty;
// Creating the "switch"
var mySwitch = new AdvancedSwitch<TrafficColor>();
// Adding a single case
mySwitch.AddHandler(TrafficColor.Green, delegate
{
result = "You may pass.";
});
// Adding multiple cases with the same action
Action redAndYellowDelegate = delegate
{
result = "You may not pass.";
};
mySwitch.AddHandler(TrafficColor.Red, redAndYellowDelegate);
mySwitch.AddHandler(TrafficColor.Yellow, redAndYellowDelegate);
// Evaluating it
mySwitch.ExecuteHandler(color, (TrafficColor[])Enum.GetValues(typeof(TrafficColor)));
Console.WriteLine(result);
}
With the creative use of anonymous delegates, you can easily add new cases to your "switch block". :)
Not that you can also use lambda expressions, and lambda blocks, eg () => { ... } instead of delegate { ... }.
You can easily use this class instead of the long switch blocks.
Original post:
If you use Visual Studio, always create swich statements with the switch code snippet. Type switch press tab twice, and it auto-generates all the possibilities for you.
Then, add a default case to the end which throws an exception, that way when testing your app you will notice that there is an unhandled case, instantly.
I mean something like this:
switch (something)
{
...
case YourEnum.SomeValue:
...
break;
default:
throw new InvalidOperationException("Default case reached.");
}
Well, there's throwing in the default case... There's no edit / compile time construct other than that.
However Strategy, Visitor and other patterns related to them may be appropriate if you choose to do it at run time.
Sample code will help with getting the best answer.
EDIT: Thanks for the sample. I still think it needs a bit of fleshing out as you dont cover whether there are some parameters that only apply to some cases etc.
Action is often used as an alias for the Command pattern and the fact that your Enum is called LogAction signifies that each value carries with it a behavior - be that implied (you stick appropriate code in a case) or explicit (in the specific Command hierarchy class).
Thus it looks to me like a usage of the Command pattern is appropriate (though your sample doesnt prove it) - i.e., have a class (potentially a hierarchy using constructor overloads or any other [set of] factory mechanisms) that keeps the state associated with the request along with the specific behaviour. Then, instead of passing an Enum value, create an appropriate LogCommand instance to the logger, which just invokes it (potentially passing a Log Sink 'receptacle' which the Command can log into). Otherwise you're poking random subsets of parameters in different places.
SEEALSO related posts:
C# - Is there a better alternative than this to ‘switch on type’?
Replace giant switch statement with what?
One possible solution is to use a SortedDictionary:
delegate void EnumHandler (args);
SortedDictionary <Enum, EnumHandler> handlers;
constructor
{
handlers = new SortedDictionary <Enum, EnumHandler> ();
fill in handlers
}
void SomeFunction (Enum enum)
{
EnumHandler handler;
if (handlers.TryGetValue (enum, out handler))
{
handler (args);
}
else
{
// not handled, report an error
}
}
This method does allow you to replace the handlers dynamically. You could also use a List as the value part of the dictionary and have multiple handlers for each enum.
Try to use reflection.
Decorate enum options with attributes that holds associated value and return this value.
Create static class of constants and use reflection for mapping enum-option to constant by name
hope this will help
Some times storing the options in a map is a good solution, you can externalize the configuration to a file too, not sure if it applies to your application.
Long code example here, and the final generic code is a little heavy (EDIT have added an extra example that eliminates the need for the angle brackets at the expense of some final flexibility).
One thing that this solution will give you is good performance - not quite as good as a straightforward switch statement, but each case statement becomes a dictionary lookup and method invocation, so still pretty good. The first call will get a performance penalty, however, due to the use of a static generic that reflects on initialisation.
Create an attribute and generic type as follows:
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class DynamicSwitchAttribute : Attribute
{
public DynamicSwitchAttribute(Type enumType, params object[] targets)
{ Targets = new HashSet<object>(targets); EnumType = enumType; }
public Type EnumType { get; private set; }
public HashSet<object> Targets { get; private set; }
}
//this builds a cache of methods for a given TTarget type, with a
//signature equal to TAction,
//keyed by values of the type TEnum. All methods are expected to
//be instance methods.
//this code can easily be modified to support static methods instead.
//what would be nice here is if we could enforce a generic constraint
//on TAction : Delegate, but we can't.
public static class DynamicSwitch<TTarget, TEnum, TAction>
{
//our lookup of actions against enum values.
//note: no lock is required on this as it is built when the static
//class is initialised.
private static Dictionary<TEnum, TAction> _actions =
new Dictionary<TEnum, TAction>();
private static MethodInfo _tActionMethod;
private static MethodInfo TActionMethod
{
get
{
if (_tActionMethod == null)
{
//one criticism of this approach might be that validation exceptions
//will be thrown inside a TypeInitializationException.
_tActionMethod = typeof(TAction).GetMethod("Invoke",
BindingFlags.Instance | BindingFlags.Public);
if (_tActionMethod == null)
throw new ArgumentException(/*elided*/);
//verify that the first parameter type is compatible with our
//TTarget type.
var methodParams = _tActionMethod.GetParameters();
if (methodParams.Length == 0)
throw new ArgumentException(/*elided*/);
//now check that the first parameter is compatible with our type TTarget
if (!methodParams[0].ParameterType.IsAssignableFrom(typeof(TTarget)))
throw new ArgumentException(/*elided*/);
}
return _tActionMethod;
}
}
static DynamicSwitch()
{
//examine the type TTarget to extract all public instance methods
//(you can change this to private instance if need be) which have a
//DynamicSwitchAttribute defined.
//we then project the attributes and the method into an anonymous type
var possibleMatchingMethods =
from method in typeof(TTarget).
GetMethods(BindingFlags.Public | BindingFlags.Instance)
let attributes = method.GetCustomAttributes(
typeof(DynamicSwitchAttribute), true).
Cast<DynamicSwitchAttribute>().ToArray()
where attributes!= null && attributes.Length == 1
&& attributes[0].EnumType.Equals(typeof(TEnum))
select new { Method = method, Attribute = attributes[0] };
//create linq expression parameter expressions for each of the
//delegate type's parameters
//these can be re-used for each of the dynamic methods we generate.
ParameterExpression[] paramExprs = TActionMethod.GetParameters().
Select((pinfo, index) =>
Expression.Parameter(
pinfo.ParameterType, pinfo.Name ?? string.Format("arg{0}"))
).ToArray();
//pre-build an array of these parameter expressions that only
//include the actual parameters
//for the method, and not the 'this' parameter.
ParameterExpression[] realParamExprs = paramExprs.Skip(1).ToArray();
//this has to be generated for each target method.
MethodCallExpression methodCall = null;
foreach (var match in possibleMatchingMethods)
{
if (!MethodMatchesAction(match.Method))
continue;
//right, now we're going to use System.Linq.Expressions to build
//a dynamic expression to invoke this method given an instance of TTarget.
methodCall =
Expression.Call(
Expression.Convert(
paramExprs[0], typeof(TTarget)
),
match.Method, realParamExprs);
TAction dynamicDelegate = Expression.
Lambda<TAction>(methodCall, paramExprs).Compile();
//now we have our method, we simply inject it into the dictionary, using
//all the unique TEnum values (from the attribute) as the keys
foreach (var enumValue in match.Attribute.Targets.OfType<TEnum>())
{
if (_actions.ContainsKey(enumValue))
throw new InvalidOperationException(/*elided*/);
_actions[enumValue] = dynamicDelegate;
}
}
}
private static bool MethodMatchesAction(MethodInfo method)
{
//so we want to check that the target method matches our desired
//delegate type (TAction).
//The way this is done is to fetch the delegate type's Invoke
//method (implicitly invoked when you invoke delegate(args)), and
//then we check the return type and parameters types of that
//against the return type and args of the method we've been passed.
//if the target method's return type is equal to or derived from the
//expected delegate's return type, then all is good.
if (!_tActionMethod.ReturnType.IsAssignableFrom(method.ReturnType))
return false;
//now, the parameter lists of the method will not be equal in length,
//as our delegate explicitly includes the 'this' parameter, whereas
//instance methods do not.
var methodParams = method.GetParameters();
var delegateParams = TActionMethod.GetParameters();
for (int i = 0; i < methodParams.Length; i++)
{
if (!methodParams[i].ParameterType.IsAssignableFrom(
delegateParams[i + 1].ParameterType))
return false;
}
return true;
}
public static TAction Resolve(TEnum value)
{
TAction result;
if (!_actions.TryGetValue(value, out result))
throw new ArgumentException("The value is not mapped");
return result;
}
}
Now do this in a Unit Test:
[TestMethod]
public void TestMethod1()
{
Assert.AreEqual(1,
DynamicSwitch<UnitTest1, Blah, Func<UnitTest1, int>>.
Resolve(Blah.BlahBlah)(this));
Assert.AreEqual(125,
DynamicSwitch<UnitTest1, Blah, Func<UnitTest1, int>>.
Resolve(Blah.Blip)(this));
Assert.AreEqual(125,
DynamicSwitch<UnitTest1, Blah, Func<UnitTest1, int>>.
Resolve(Blah.Bop)(this));
}
public enum Blah
{
BlahBlah,
Bloo,
Blip,
Bup,
Bop
}
[DynamicSwitchAttribute(typeof(Blah), Blah.BlahBlah)]
public int Method()
{
return 1;
}
[DynamicSwitchAttribute(typeof(Blah), Blah.Blip, Blah.Bop)]
public int Method2()
{
return 125;
}
So, given a value of TEnum, and your preferred 'action' type (in your code you would appear to be simply returning nothing and modifying the internal state of the class), you simply consult the DynamicSwitch<> class, ask it to resolve a target method, and then invoke it inline (passing the target object on which the method will be invoked as the first parameter).
I'm not really expecting any votes for this - it's a MAD solution to be honest (it does have the advantage of being able to be applied for any enum type, and even discreet values of type int/float/double, as well as supporting any delegate type) - so perhaps it's a bit of a sledgehammer!
EDIT
Once you have a static generic like this, angle-bracket hell ensues - so we want to try and get rid of them. A lot of the time, this is done by type inference on method parameters etc - but we have a problem here that we can't easily infer a delegate's signature without repeating the method call i.e. (args) => return.
However, you seem to require a method that takes no parameters and returns void, so you can close over this behemoth generic by fixing the delegate type to Action, and throw a fluid API into the mix as well (if that's your kind of thing):
public static class ActionSwitch
{
public class SwitchOn<TEnum>
{
private TEnum Value { get; set; }
internal SwitchOn(TEnum value)
{
Value = value;
}
public class Call<TTarget>{
private TEnum Value { get; set; }
private TTarget Target { get; set; }
internal Call(TEnum value, TTarget target)
{
Value = value;
Target = target;
Invoke();
}
internal void Invoke(){
DynamicSwitch<TTarget, TEnum, Action<TTarget>>.Resolve(Value)(Target);
}
}
public Call<TTarget> On<TTarget>(TTarget target)
{
return new Call<TTarget>(Value, target);
}
}
public static SwitchOn<TEnum> Switch<TEnum>(TEnum onValue)
{
return new SwitchOn<TEnum>(onValue);
}
}
Now add this to the test project:
[TestMethod]
public void TestMethod2()
{
//no longer have any angle brackets
ActionSwitch.Switch(Blah.Bup).On(this);
Assert.IsTrue(_actionMethod1Called);
}
private bool _actionMethod1Called;
[DynamicSwitch(typeof(Blah), Blah.Bup)]
public void ActionMethod1()
{
_actionMethod1Called = true;
}
Only issue with this (apart from the complexity of the solution :) ) is that you'd have to re-build this static wrapper type whenever you want to use a new type of target delegate for a dynamic switch elsewhere. You could generate a generic version based on the Action<...> and Func<...> delegates that incorporates TArg1, TArg(n) and TReturn (if Func<>) - but you'd end up writing a lot more code.
Perhaps I'll turn this into an article on my blog and do all of that - if I get the time!

Categories