C# simpler run time generics - c#

Is there a way to invoke a generic function with a type known only at run time?
I'm trying to do something like:
static void bar()
{
object b = 6;
string c = foo<typeof(b)>();
}
static string foo<T>()
{
return typeof (T).Name;
}
Basically I want to decide on the type parameter only at run time, but the function I'm calling depends on the type parameter.
Also I know this can be done with reflections... but it's not the nicest solution to the problem...
I'm sort of looking for dynamic features in C#...
I'm writhing a bridge between two classes the first one is basically a big tree with different types of of objects (composite by interface) the other is a sort of a "super visitor".
the supper visitor accepts key-value dictioneries that map types to object it looks like:
dic.Add(object value)
and T is not necessarily the type of the value... a lot of times it isn't...
I know it's written poorly, but i can't fix it...
I can work around it, but only at runtime...
I already did it with reflections, but if there's a better way to do it without them i would be happy to learn...
Thank you

This is a bit of a hack but you can get dynamic to do the reflection work for you by something like,
class Program
{
static void Main(string[] args)
{
var b = 6;
var t = (dynamic)new T();
var n = t.Foo(b);
}
class T
{
public string Foo<T>(T a)
{
return typeof(T).Name;
}
}
}
Here the dynamic call will extract the type of b and use it as a type parameter for Foo().

You can use dynamic keyword if you're using .NET 4. In a word, the type of the variable will be resolved at run time so it is a super generic type ;) You can read a article here or read the MSDN documentation

Saly refelction is THE solution to the problem, whether it is nice or not is irrelevant here. It is the runtime designed mechanism to achieve exactly this. As there is no parameter or generics to use as input, this is the only way to do it - it is also senseless. As in: your example is bad. Because in the example the type is hardcoded.
If the method where b exists has b as generic parameter, the type is available for passing to foo. If not - reflection is THE way to go, albeit the syntax looks clumsy. Only one time, though.

This I believe is the only way:
var foo = typeof(Foo<>).MakeGenericType(typeof (bar));

You can set up a class which takes a type parameter at run time which can be used in the methods in that class.
public class GenericClass<T>()
{
ICommonInterface TheObject;
public GenericClass(T theObject)
{
TheObject = theObject;
}
public string GetName()
{
return TheObject.Name;
}
}
But this is only really useful if the Types being passed in share interfaces so have common properties between them. In your example it seems that relection is the answer as depending on the type you want to access specific properties.

Related

Explicitly cast base class to derived class

Problem: I have 2 types which are result sets of 2 different procedures in DB:
Proc1Result, Proc2Result (We had to split them - but they are basically the same as comes for input/output)
I then decided that I could make use of an interface to switch between needed procedures on runtime - but this means I would need 1 common type to which i could convert Proc1Result and Proc2Result
Just so I do not need to maintain this new class (create all the properties, add/remove if anything changes in DB result) - I derived this class from one of the results:
public class DerivedClassForInterface : Proc1Result {}
Then I implemented explicit cast from the 2nd proc which works fine, but when I want to implement explicit cast from base class to derived class - it wont allow me (since it kinda already "does" - but it fails at runtime):
public class DerivedClassForInterface : Proc1Result
{
//ok - and works as expected
public static explicit operator DerivedClassForInterface(Proc2Result v)
{
return new DerivedClassForInterface
{
...
};
}
//fail: 'user-defined' conversations to or from a base class are not allowed
public static explicit operator DerivedClassForInterface(Proc1Result v)
{
return new DerivedClassForInterface
{
...
};
}
}
so this works:
//result2 is of type Proc1Result
DerivedClassForInterface castedResult = (DerivedClassForInterface)result2;
//compiles - works as expected at runtime
but this does not:
//result1 is of type Proc1Result
DerivedClassForInterface castedResult = (DerivedClassForInterface)result1;
//compiles - conversation fails at runtime
So why I can not write my own explicit operator if you can not cast from base class to derived class?
Interesting that compiler allows me to cast from base to derived class, and yet it does not work at runtime.
Probably I will go just for simple functions which will do the "casting" for me. Anyone can suggest a better solution (keep in mind that I would like to keep "DerivedClassForInterface" to obey changes in "Proc1Result" (or "Proc2Result" - doesn't matter))
EDIT
#Peter Duniho - Here the types "Proc1Result" and "Proc2Result" are generated as results from stored procedures (linq2sql). I would like to have a code which I wont need to touch when output of those procedures change (since there are bunch of procedures we need to segment - and implementing new modules could and often does add more output).
Proc1 and Proc2 are basically same stored procedures (they require exactly the same input and provides same output (type-wise not data-wise)). Both of them work with different segments of data and are required to be separate.
Sorry for making this confusing (was at end of my working day...) and not clarifying - the question here actually is:
Why compiler lets me cast from base to derived class when runtime causes exception? And why I can not implement this casting myself (... because it kinda already does - but it just does not work at runtime?)
So from where I stand - it looks the following:
- I can not implement this cast because it already exists
- Yet it is doomed to not work
Here is "Minimal, Complete, and Verifiable code example" (thanks for the link):
//results from stored procedures in database which got splitted appart (linq 2 sql)
class Proc1Result { }
class Proc2Result { }
//
class DerivedClassForInterface : Proc1Result
{
public static explicit operator DerivedClassForInterface(Proc2Result v)
{
//this part would be exported in generic function
var derivedClassInstance = new DerivedClassForInterface();
var properties = v.GetType().GetProperties();
foreach (var property in properties)
{
var propToSet = derivedClassInstance.GetType().GetProperty(property.Name);
if (propToSet.SetMethod != null) propToSet.SetValue(derivedClassInstance, property.GetValue(v));
}
return derivedClassInstance;
}
}
interface IProcLauncher
{
DerivedClassForInterface GetNeededData();
}
class ProcLauncher1 : IProcLauncher
{
public DerivedClassForInterface GetNeededData()
{
var dataFromDb = new Proc1Result();/*just ilustrative*/
return (DerivedClassForInterface)dataFromDb;
}
}
class ProcLauncher2 : IProcLauncher
{
public DerivedClassForInterface GetNeededData()
{
var dataFromDb = new Proc2Result();/*just ilustrative*/
return (DerivedClassForInterface)dataFromDb;
}
}
class Program
{
static void Main(string[] args)
{
bool causeInvalidCastException = true;
IProcLauncher procedureLauncher;
if (causeInvalidCastException) procedureLauncher = new ProcLauncher1();
else procedureLauncher = new ProcLauncher2();
var result = procedureLauncher.GetNeededData();
Console.WriteLine("I got here!");
}
}
The idea was:
- Not have to change any code if output of procedures change.
- Decide at runtime which proc to use.
- Export the convertation part as generic function.
- Got to be injectable.
I can solve this - let say - by just 1 generic function which will handle conversation for all cases, but the question is above in bold.
I implemented the converting the following way:
class BaseConverter
{
protected T Convert<T, X>(X result)
{
var derivedClassInstance = Activator.CreateInstance<T>();
var derivedType = derivedClassInstance.GetType();
var properties = result.GetType().GetProperties();
foreach (var property in properties)
{
var propToSet = derivedType.GetProperty(property.Name);
if (propToSet.SetMethod != null)
{
propToSet.SetValue(derivedClassInstance, property.GetValue(result));
}
}
return derivedClassInstance;
}
protected List<T> Convert<T, X>(List<X> listResult)
{
var derivedList = new List<T>();
foreach (var r in listResult)
{
//can cope with this - since there will not ever be many iterations
derivedList.Add(Convert<T, X>(r));
}
return derivedList;
}
}
So interface implementation classes would inherit from it:
class ProcLauncher2 : BaseConverter, IProcLauncher
{
public DerivedClassForInterface GetNeededData()
{
var dataFromDb = new Proc2Result();/*just ilustrative*/
//usage (works for single result or list if I need a list returned):
return Convert<DerivedClassForInterface, Proc2Result>(dataFromDb);
}
//other methods...
}
Yet - it is not clear for me - why there is already cast from base class to derived - if that does not work. Imo - it should not be there and throw error at compile time.
I don't understand your question very well. You seem to say that the compiler lets you write the code you posted, but that it fails at runtime. This isn't my experience. I get a compile-time error on the explicit conversion operation for the base class:
error CS0553: 'Derived.explicit operator Derived(Base1)': user-defined conversions to or from a base class are not allowed
Seems pretty clear to me. As for why you aren't allowed to write code like that, you'd have to ask the language designers to know for sure, but it seems like a reasonable restriction to me. There already is a safe, built-in conversion from any base class to a derived class of that base class, as long as the base class instance is in fact an instance of the derived class. It would be confusing and likely to lead to bugs if programmers were allowed to make additional conversions, never mind greatly complicate the language specification's rules for the casting/conversion operator.
As for the broader problem, I don't understand the approach you've chosen. You're designing the classes exactly upside-down from the way one would normally do this. If you have a number of classes that all have shared members, you want to be able to treat all those classes as the same in some context, and you want to be able to implement those shared members exactly once and share them among the other classes, you would put all those members in a single base class, and then derive all your various types from that class.
I don't even see how your current approach addresses this concern:
Just so I do not need to maintain this new class (create all the properties, add/remove if anything changes in DB result)
Since Proc2Result doesn't inherit Proc1Result, if Proc1Result changes, you'll have to go change Proc2Result to match anyway. And any other similar types. And the DerivedClassForInterface class. And you have to change all the explicit operators. How is that better?
I would think you would prefer something like:
class BaseClassForInterface
{
// declare all shared members here
}
class Proc1Result : BaseClassForInterface { ... }
class Proc2Result : BaseClassForInterface { ... }
Then, for each new Proc...Result class, you simply inherit the base class, no need to re-write the members, and the conversion from each Proc...Result class is trivial. You don't even need to use the casting/conversion operator; the language already knows how to implicitly convert from derived classes to base classes, because the derived classes are the base classes.
This is, in fact, the standard way to use OOP. It's one of the most fundamental features of any OOP language.
If that doesn't get you back on track, you'll need to improve the question, so that it's more clear what you are doing and why. You'll also need to provide a good Minimal, Complete, and Verifiable code example that clearly illustrates your question, explaining precisely what that code does and what you want it to do instead.
Addendum:
Thanks for the edit. Your question is a lot more specific and clear now. I still have questions, but at least I understand the real context.
It seems to me that you already understand most of the basic answer to your question:
Why compiler lets me cast from base to derived class when runtime causes exception? And why I can not implement this casting myself (... because it kinda already does - but it just does not work at runtime?)
So from where I stand - it looks the following:
- I can not implement this cast because it already exists
- Yet it is doomed to not work
I.e. yes, I believe the language disallows this because there is already a built-in cast, and yes the exact approach you seek is doomed to not work.
As far as this part goes:
The idea was:
- Not have to change any code if output of procedures change.
- Decide at runtime which proc to use.
- Export the convertation part as generic function.
- Got to be injectable.
If I understand the first point, this is why you inherit one of the stored procedure types. So that you get the property declarations for free. Seems a little hacky to me, but I admit I do understand the motivation.
As I understand the third point above and your statement after in your post, you already know how you can write a generic method to do the conversion. E.g. something like:
DerivedClassForInterface ConvertToClassForInterface<T>(T t)
{
DerivedClassForInterface result = new DerivedClassForInterface();
Type resultType = typeof(DerivedClassForInterface);
PropertyInfo[] properties = typeof(T).GetProperties();
foreach (var property in properties)
{
var propToSet = resultType.GetProperty(property.Name);
if (propToSet.SetMethod != null)
{
propToSet.SetValue(result, property.GetValue(t));
}
}
return result;
}
I.e. essentially the code you show in your explicit operator (with some minor cleanup/optimization). Or maybe you aren't using the term "generic" literally, and just mean "general purpose". Obviously there's very little in the above that really benefits from the method being generic; you could just as easily use GetType() on the parameter, just as your explicit operator does.
Unfortunately, I don't know how the criteria "Got to be injectable" fits in here. Injectable, how? Do you mean you want to inject the code somewhere else? Or do you mean that the code needs to be compatible with an AOP system, or some other form of code injection applied to it?
Ignoring that part, which I don't understand, I would actually just leverage the compiler and runtime to do all the heavy lifting for me (including caching the reflection stuff, which in your code is going to be very slow). You could write a class like this:
class Wrapper
{
private dynamic _data;
public string Value { get { return _data.Value; } }
public Wrapper(dynamic data)
{
_data = data;
}
}
Given a couple of other classes like this:
class Result1
{
public string Value { get; set; }
}
class Result2
{
public string Value { get; set; }
}
Then you can use it like this:
Result1 r1 = new Result1 { Value = "result 1" };
Result2 r2 = new Result2 { Value = "result 2" };
Wrapper w1 = new Wrapper(r1), w2 = new Wrapper(r2);
Console.WriteLine("w1 result: " + w1.Value);
Console.WriteLine("w2 result: " + w2.Value);
I.e. just create an instance of Wrapper, passing the relevant object (in your case, this would be the generated type's from the stored procedure). The downside is, of course, that you do have to add properties to the Wrapper type to match your stored procedure. But I'm not convinced that's a bad thing. Even if you've somehow arranged it so that none of the rest of the code has to change, it's a relatively minor maintenance task.
And I suspect that altering the stored procedure requires changes elsewhere in the code anyway, to explicitly refer to the properties. Because after all, if the rest of the code is similarly completely agnostic regarding the specific class members (i.e. uses reflection all the way), then you could just pass the result objects around as object types, and not worry about the wrapper at all.

Implictly casting a dynamic object at runtime

Say I have the following code:
class MyField : DynamicObject
{
public dynamic Value { get; private set; }
public override bool TryConvert(ConvertBinder binder, out object result)
{
result = binder.Type == Value.GetType() ? Value : null;
return result != null;
}
public MyField(dynamic v)
{
Value = v;
}
}
// ...
public static class Program
{
static void doSomething(ulong address) { /* ... */ }
public void Main(string[] args)
{
dynamic field = new MyField((ulong)12345);
doSomething(field); // fails as field is not a ulong.
doSomething((ulong)field); // succeeds as field can be casted to a ulong.
ulong field2 = field; // also succeeds
}
}
Is there a way to get the first call to doSomething to succeed? I'm writing a library to read a particular file format which uses serialized C-style structures; reading the file entails reading these saved structure definitions and then "populating" them with the data contained in the rest of the file. I have a "structure" DynamicObject class (to support dot-notation access) and a "field" DynamicObject class, which is primarily necessary to hold additional information on the contents of the field; although I could probably get rid of it, it would make certain other operations more difficult. What I'd like to do is just "pretend" MyField is a certain type (well, technically just any built-in primitive or array of primitives, including 2D arrays) and implicitly convert it to that type. However, the runtime fails to try to implicitly convert field to the type required by the underlying method signature if field doesn't match the type required.
In the vein of Greg's answer, I came up with a solution that makes the runtime happy. It's not exactly what I was originally looking for, but it seems like the best solution.
Since I already have a large if-else tree in my source wherein I take an array of bytes and interpret them as an actual value-type, and indeed my current source does use an underlying generic MyField<T>, so this works fine. I can't recall why I wanted MyField to be dynamic in the first place.
Anyway, this is a modified solution.
class MyField<T>
{
public dynamic Value { get; private set; }
public MyField(dynamic v) { Value = v; }
public static implicit operator T(MyField field)
{
return (T)field.Value;
}
}
I keep coming back to wanting the runtime to just figure out what it needs to cast MyField to at runtime but I guess it's not that big of a deal. If anyone comes up with something better, let me know. I'm going to keep this question open in the meantime.
You potentially might want to look into Generics. Coupled with an interface may make the dynamic usage far more viable.
public interface Helper <TInput, TOutput>
{
<TOutput> DoSomething(TInput input);
}
So when you use this interface with a class, you'll implement your type for both input and output. Which will give you quite a bit of flexibility, which should avoid those cast that you mentioned earlier. A small example, I mean you could obviously adjust it based on needs but I still don't understand what you're trying to really do.

Expose Action<T> as Action<object>

I'm creating a framework that contains a wrapper around a library (specifically SharpBrake) that performs all interaction with SharpBrake via reflection so there's no hard dependency on the library to 3rd parties of my framework.
If 3rd parties of my framework wants to use SharpBrake, they can just stuff the SharpBrake.dll into the bin folder, but if they don't, they can just forget about it. If my framework had explicit references to SharpBrake types, users of my framework would get exceptions during runtime of SharpBrake.dll missing, which I don't want.
So, my wrapper first loads SharpBrake.dll from disk, finds the AirbrakeClient type, and stores a delegate pointing to the AirbrakeClient.Send(AirbrakeNotice) method in a private field. My problem, however, is that since the Send() method takes an AirbrakeNotice object and I can't reference the AirbrakeNotice object directly, I need to somehow convert the Send() method to an Action<object>.
I have a strong feeling this isn't possible, but I want to explore all options before settling on exposing Delegate and using DynamicInvoke(), which I assume is far from optimal, performance-wise. What I would love to do is the following:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
MethodInfo sendMethod = clientType.GetMethod("Send", new[] { noticeType });
object client = Activator.CreateInstance(clientType);
Type actionType = Expression.GetActionType(noticeType);
Delegate sendMethodDelegate = Delegate.CreateDelegate(actionType, client, sendMethod);
// This fails with an InvalidCastException:
Action<object> sendAction = (Action<object>)sendMethodDelegate;
However, this fails with the following exception:
System.InvalidCastException: Unable to cast object of type 'System.Action`1[SharpBrake.Serialization.AirbrakeNotice]' to type 'System.Action`1[System.Object]'.
Obviously, because sendMethodDelegate is an Action<AirbrakeNotice> and not an Action<object>. Since I can't mention AirbrakeNotice in my code, I'm forced to do this:
Action<object> sendAction = x => sendMethodDelegate.DynamicInvoke(x);
or just exposing the Delegate sendMethodDelegate directly. Is this possible? I know that there's chance of getting into situations where the object can be of a different type than AirbrakeNotice which would be bad, but seeing how much you can mess up with reflection anyway, I'm hoping there's a loophole somewhere.
If you're happy to use expression trees, it's reasonably simple:
ConstantExpression target = Expression.Constant(client, clientType);
ParameterExpression parameter = Expression.Parameter(typeof(object), "x");
Expression converted = Expression.Convert(parameter, noticeType);
Expression call = Expression.Call(target, sendMethod, converted);
Action<object> action = Expression.Lambda<Action<object>>(call, parameter)
.Compile();
I think that's what you want...
If you don't need below C# 4 support you can get much greater performance using the dynamic vs DynamicInvoke.
Action<dynamic> sendAction = x => sendMethodDelegate(x);
Actually I guess you wouldn't even need the above if you can use dynamic, because it would increase performance and simplify everything if you just did:
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
dynamic client = Activator.CreateInstance(clientType);
...
client.Send(anAirbrakeNotice);
But if you need to support .net 3.5 jon skeets answer with expression trees is definitely the way to go.
From my comment on the OP:
I'd avoid extended use of reflections if you are concerned about performance. If you can come up with an interface for the class(es) you are using, then I'd create one. Then write a wrapper that implements the interface by calling into the SharpBreak code, and stuff it in a separate DLL. Then dynamically load just your wrapper assembly and concrete wrapper type(s), and call into that interface. Then you don't have to do reflections at a method level.
I'm not sure all the classes you'd need, but here's a simple example of how you can hook into that library with loose coupling based on interfaces.
In your program's assembly:
public IExtensions
{
void SendToAirbrake(Exception exception);
}
public static AirbreakExtensions
{
private static IExtensions _impl;
static()
{
impl = new NullExtensions();
// Todo: Load if available here
}
public static void SendToAirbrake(this Exception exception)
{
_impl.SendToAirbrake(exception);
}
}
internal class NullExtensions : IExtensions // no-op fake
{
void SendToAirbrake(Exception exception)
{
}
}
In a load-if-available (via reflections) assembly
public ExtensionsAdapter : IExtensions
{
void SendToAirbrake(Exception exception)
{
SharpBrake.Extensions.SendToAirbrake(exception);
}
}
The advantage of this approach is that you only use reflections once (on load), and never touch it again. It is also simple to modify to use dependency injection, or mock objects (for testing).
Edit:
For other types it will take a bit more work.
You might need to use the Abstract Factory pattern to instantiate an AirbrakeNoticeBuilder, since you need to deal directly with the interface, and can't put constructors in interfaces.
public interface IAirbrakeNoticeBuilderFactory
{
IAirbrakeNoticeBuilder Create();
IAirbrakeNoticeBuilder Create(AirbrakeConfiguration configuration);
}
If you're dealing with custom Airbreak structures, you'll have even more work.
E.g. for the AirbrakeNoticeBuilder you will have to create duplicate POCO types for any related classes that you use.
public interface IAirbrakeNoticeBuilder
{
AirbrakeNotice Notice(Exception exception);
}
Since you're returning AirbrakeNotice, you might have to pull in nearly every POCO under the Serialization folder, depending on how much you use, and how much you pass back to the framework.
If you decide to copy the POCO code, including the whole object tree, you could look into using AutoMapper to convert to and from your POCO copies.
Alternately, if you don't use the values in the classes you're getting back, and just pass them back to the SharpBreak code, you could come up with some sort of opaque reference scheme that will use a dictionary of your opaque reference type to the actual POCO type. Then you don't have to copy the whole POCO object tree into your code, and you don't need to take as much runtime overhead to map the object trees back and forth:
public class AirbrakeNotice
{
// Note there is no implementation
}
internal class AirbreakNoticeMap
{
static AirbreakNoticeMap()
{
Map = new Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice>();
}
public static Dictionary<AirbreakNotice, SharpBreak.AirbreakNotice> Map { get; }
}
public interface IAirbrakeClient
{
void Send(AirbrakeNotice notice);
// ...
}
internal class AirbrakeClientWrapper : IAirbrakeClient
{
private AirbrakeClient _airbrakeClient;
public void Send(AirbrakeNotice notice)
{
SharpBreak.AirbrakeNotice actualNotice = AirbreakNoticeMap.Map[notice];
_airbrakeClient.Send(actualNotice);
}
// ...
}
internal class AirbrakeNoticeBuilderWrapper : IAirbrakeNoticeBuilder
{
AirbrakeNoticeBuilder _airbrakeNoticeBuilder;
public AirbrakeNotice Notice(Exception exception)
{
SharpBreak.AirbrakeNotice actualNotice =
_airbrakeNoticeBuilder.Notice(exception);
AirbrakeNotice result = new AirbrakeNotice();
AirbreakNoticeMap.Map[result] = actualNotice;
return result;
}
// ...
}
Keep in mind that you only need to wrap the classes and parts of the public interface that you're going to use. The object will still behave the same internally, even if you don't wrap its entire public interface. This might mean you have to do less work, so think hard and try to wrap only what you need now, and what you know you're going to need in the future. Keep YAGNI in mind.
The programming style I have come to really like for problems like this is to write as much strongly-typed code as possible, and then hand off the logic from the dynamically-typed code to the strongly-typed code. So I would write your code like this:
//your code which gets types
Type clientType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeClient");
Type noticeType = exportedTypes.FirstOrDefault(type => type.Name == "AirbrakeNotice");
//construct my helper object
var makeDelegateHelperType=typeof(MakeDelegateHelper<,>).MakeGenericType(clientType, noticeType);
var makeDelegateHelper=(MakeDelegateHelper)Activator.CreateInstance(makeDelegateHelperType);
//now I am in strongly-typed world again
var sendAction=makeDelegateHelper.MakeSendAction();
And this is the definition of the helper object, which is able to get away with fewer reflectiony calls.
public abstract class MakeDelegateHelper {
public abstract Action<object> MakeSendAction();
}
public class MakeDelegateHelper<TClient,TNotice> : MakeDelegateHelper where TClient : new() {
public override Action<object> MakeSendAction() {
var sendMethod = typeof(TClient).GetMethod("Send", new[] { typeof(TNotice) });
var client=new TClient();
var action=(Action<TNotice>)Delegate.CreateDelegate(typeof(Action<TNotice>), client, sendMethod);
return o => action((TNotice)o);
}
}

Compile time generics syntax

class GenericWrapper<T>
{
}
class WrapperInstance : GenericWrapper<string>
{
}
class Usage
{
public static Usage Create<T1, T2> (T2 t2) where T1 : GenericWrapper<T2>
{
return null;
}
}
...
// works
Usage.Create<WrapperInstance, string>("bar");
// doesnt work
Usage.Create<WrapperInstance>("bar");
I suspect the answer is no, but is there a way I can make the last line compile?
I want the compiler to force me to provide a string argument without having to know or first go and examine WrapperInstance to see what T of GenericWrapper it implements.
I know I can make it compile by either using the first method or by taking object as the argument and doing runtime checking, but thats not the question ;) I largely suspect these are my only two options.
Thanks
I suspect the answer is no, but is there a way I can make the last line compile?
No. Create has two generic type parameters. You either specify none or you specify both. In the case of none, the compiler will try to infer the types from the invocation arguments. However, in this case it can not because T1 never appears in the argument list. Therefore you must specify both.
There are two problems here:
You want to infer just one type argument, and specify the other. You can't do that with normal type inference. However, you could make Usage generic, thus specifying one type argument there, and letting the other be inferred using the generic method:
Usage<WrapperInstance>.Create("foo");
That's something I've often done before, but that just leads to the second problem...
The type parameter you want to specify (T1) is constrained by the one you want to infer (T2). The above example can't do that, as Usage<WrapperInstance> doesn't "have" a T2 to validate... and you can't constrain an existing type parameter on a generic method - only ones which are introduced in the method.
There's one way I think we could do this:
public class Usage
{
public static Usage<T2> For<T2>(T2 t2)
{
return new Usage<T2>(t2);
}
}
public class Usage<T2>
{
private readonly T2 t2; // Assuming we need it
public Usage(T2 t2)
{
this.t2 = t2;
}
// I don't know what return type you really want here
public static Foo Create<T1>() where T1 : GenericWrapper<T2>
{
// Whatever
}
}
You'd use it like this:
Usage.Foo("bar").Create<WrapperInstance>();
Without knowing more about what you're trying to do, I don't know whether or not that's helpful - but it does manage to accomplish what you were after in terms of:
Validating the WrapperInstance type argument
Inferring the string type argument

Is the StaticFactory in codecampserver a well known pattern?

UPDATE: this is a duplicate of
Is the StaticFactory in codecampserver a well known pattern?
Edit: Please note that this answer was given before the question was completely changed over in an edit. Because of that, it now refers to things that were only present in the question as originally stated. I beg your pardon for all the "dangling pointers". :-)
Short answer:
With the code you've posted, I don't see an alternative to casting to IFoo<T>. If you don't, the compiler will give a warning (on my machine, at least).
More elaborate answer:
Does your code actually have to be that way? More specifically, do you need the cast in question in the first place?
I assume you are going to call your factory method more or less like this:
var stringFoo = FooFactory.CreateFoo<string>();
You have to provide the template parameter (string in this case) explicitly because it cannot be derived from any method argument (in this case because there aren't actually any at all). Obviously, the factory method will return an IFoo<string>.
Now, since you have to explicitly specify the type at run-time, you could just as well write:
var stringFoo = StringFoo.Create();
and therefore have a factory method inside StringFoo, like this, that unconditionally does the obvious:
public class StringFoo : IFoo<string>
{
...
public static StringFoo Create() // or alternatively, return an IFoo<string>
{
return new StringFoo();
}
}
By applying this pattern to other IFoo<T> implementations too, this will save you the if chain or switch block inside FooFactory.CreateFoo<T>, make your code easier, and get rid of the necessity to cast (which you are concerned about).
Don't get me wrong, I'm aware that factory methods supporting more than one object type are useful in some cases; but it seems in your case it causes more trouble than it's worth.
P.S.: You might find one aspect of some IoC containers interesting. They usually need to be configured, and this encompasses a process where you register concrete types (i.e. implementation classes) for abstract interfaces; for example (here using Autofac):
var builder = new ContainerBuilder();
builder.RegisterType<StringFoo>().As<IFoo<string>>();
Then later, you can request an object instance of an abstract type:
using (var container = builder.Build())
{
var stringFoo = container.Resolve<IFoo<string>>();
...
}
The Resolve method is the interesting part. You provide it with an abstract type, and using the registered types, it will return a concrete object of type StringFoo. Look into it, if it doesn't sound like overkill to you! :-)
Can you describe the problem you are solving with this mechanism? There is most likely a clearer way to approach it.
Edit
And yes, the code smells. You have left room open for any type, except you then constrain it back to a single type, and generate a run-time exception. Why have a type parameter in that case?
You could try something like this...
public static class FooFactory
{
private static readonly Dictionary<Type, Type> FooTypesLookup;
static FooFactory()
{
FooTypesLookup = (from type in typeof(FooFactory).Assembly.GetExportedTypes()
let fooInterface =
type.GetInterfaces().FirstOrDefault(
x => x.IsGenericType && x.GetGenericTypeDefinition() == typeof(IFoo<>))
where fooInterface != null
let firstTypeArgument = fooInterface.GetGenericArguments().First()
select new { Type = type, TypeArgument = firstTypeArgument })
.ToDictionary(x => x.TypeArgument, x => x.Type);
}
public static IFoo<T> CreateFoo<T>()
{
var genericArgumentType = typeof(T);
Type closedFooType;
return FooTypesLookup.TryGetValue(genericArgumentType, out closedFooType)
? (IFoo<T>) Activator.CreateInstance(closedFooType)
: null;
}
}
Or better yet, introduce your favorite IoC container (Windsor, structure map, etc) and register all types that implement IFoo in there and then resolve them when needed in place of the Activator.CreateInstance call.

Categories