I've something along this lines:
public class Something
{
private IDictionary<object,Activity> fCases;
public IDictionary<object,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
}
public sealed class Something<T> : Something
{
private IDictionary<T,Activity> fCases;
public override IDictionary<T,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
}
Note: override is not accepted on this case
Due to heavy Reflection usage there are situations where I've to downcast from Something<T> to Something but, I guess because Cases property is hidden, I'm losing Cases data.
How can I circumvent this situation? I've tried to use where T:object but that isn't accepted also.
EDIT:
This is an example of why I need inheritance:
if (someVar is Something) {
if (someVar.GetType().IsGenericType)
{
// Construct AnotherObject<T> depending on the Something<T>'s generic argument
Type typeArg = someVar.GetType().GetGenericArguments()[0],
genericDefinition = typeof(AnotherObject<>),
typeToConstruct = genericDefinition.makeGenericType(typeArgs);
object newAnotherObject = Activator.CreateInstance(typeToConstruct);
// Pass Something 'Cases' property to AnotherObject<T>
constructedType.InvokeMember(
"Cases",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.SetProperty,
null,
newActivity,
new Object[] { someVar.Cases });
}
}
But, because 'Cases' is hidden, it will be always null. Without inheritance I would have to write a BIG if-then-else with all the possible generic arguments. And, believe me, I do really have to use someVar is Something and Reflection to construct all this objects. This is a big generic API being converted to other big generic API and so they should not known each other and the conversion should be as transparent as possible.
You won't be able to override it like that, and for good reason.
Imagine:
Something x = new Something<string>();
Button key = new Button();
x.Cases[key] = new Activity();
If your override worked, that would be trying to store a Button reference as a key in Dictionary<string, Activity>. That would be a Bad Thing.
Perhaps inheritance isn't actually appropriate in this case? If you could explain more about what you're trying to achieve, that would help. Perhaps you don't really need the dictionary as a property? Maybe just a method to fetch by key?
This is flat-out not going to work because the IDictionary<TKey, TValue> interface is invariant. An IDictionary<object, Activity> cannot be treated as an IDictionary<T, Activity>.
What you could do, rather than exposing an entire IDictionary<T, Activity> in your derived class, is simply delegate the calls you want to expose, like this:
public class Something
{
protected IDictionary<object, Activity> Cases { get; set; }
}
public sealed class Something<T> : Something
{
public Activity GetCase(T key)
{
return Cases[key];
}
public void AddCase(T key, Activity case)
{
Cases.Add(key, case);
}
// etc. etc.
}
Alternatively, you could also define your own contravariant interface, something like:
interface IKeyedCollection<in TKey, TValue>
{
TValue this[TKey key] { get; set; }
void Add(TKey key, TValue value);
}
For the above interface, an IKeyedCollection<object, Activity> could act as an IKeyedCollection<T, Activity> because every T is an object.
If you attempt to expose incompatible types at the different levels you're going to keep running into problems because at the end of the day you'll end up having to maintain 2 separate objects (or 1 custom object with 2 interfaces it can't completely satisfy).
These types are incompatible because there are values which can be added to IDictionary<object, Activity> which cannot be added to every instantiation of IDictionary<T, Activity>. Imagine for instance T is instatiated as string and the developer uses a int key elsewhere via Something. This creates a real problem for Something<string> implementations.
The way I would approach this is to change the base type Something to not expose a concrete type but instead to expose the relevant APIs.
public abstract class Something {
public abstract IEnumerable<KeyValuePair> GetElements();
public abstract bool TryGetValue(object key, out Activity value);
}
This gives Something<T> the flexbility it needs to properly sub-class Something and be very expressive about the types it wants to expose
public sealed class Something<T> : Something {
private IDictionary<T,Activity> fCases;
public override IDictionary<T,Activity> Cases
{
get { return fCases; }
set { fCases = value; }
}
public override IEnumerable<KeyValuPair<object, Activity>> GetElements() {
foreach (var cur in fCases) {
yield return new KeyValuePair<object, Activity>(cur.Key, cur.Value);
}
}
public override bool TryGetValue(object key, out Activity activity) {
try {
T typedKey = (T)key;
return fCases.TryGetValue(typedKey, out activity);
} catch (InvalidCastException) {
activity = null;
return false;
}
}
}
}
During heavy reflection usage I also had the need to 'upcast' from generic types. I knew certain calls would be compatible, but I didn't know the types at compile time. If you look at it this way, it is not really 'upcasting' a generic type, but rather, allowing to use generics during reflection by generating the correct downcasts.
To this end I created a helper method to create delegates along the lines of Delegate.CreateDelegate, but allowing to create a less generic delegate. Downcasts are generated where necessary. I explain it in detail on my blog.
MethodInfo methodToCall = typeof( string ).GetMethod( "Compare" );
Func<object, object, int> unknownArgument
= DelegateHelper.CreateDowncastingDelegate<Func<object, object, int>>(
null, methodToCall );
unknownArgument( "test", "test" ); // Will return 0.
unknownArgument( "test", 1 ); // Will compile, but throw InvalidCastException.
A bit later I had a need to create entire less generic wrapper classes for generic classes, so that all method calls would immediately become available as less generic calls during reflection. This might or might not be useful in your scenario as well. For this purpose I created a (not as thoroughly tested) method which allows to generate this wrapper class at runtime using emit. It is available in my open source library. I haven't written about this yet, so when interested you'll just have to try it out (and possibly see it fail since it's still quite new).
Related
I am new to C#. I am trying to implement a Dictionary in C# whose Java-equivalent is:
HashMap<string, Variable<?>> dictionary
Here is the detailed Java version of what I'm trying to do: Java how to manage user-defined variables
In C# so far I have something like this:
interface IVariable { }
public class Variable<T> : IVariable
{
public T myValue { get; set; }
}
Dictionary<string, IVariable> vars = new Dictionary<string, IVariable>();
Then I try to do this:
Variable<int> age = new Variable<int>();
age.myValue = 12;
vars.Add("age", age);
IVariable theVar;
if (vars.TryGetValue("age", out theVar) {
Console.WriteLine("fetched age is " + theVar.myValue);
}
I run into trouble in the last line because the compiler doesn't recognize the myValue member of a theVar because it is an IVariable.
In this simple example maybe I could declare theVar to be a Variable<int> instead of an IVariable but I haven't tried it because it would require a priori knowledge about what kind of variable I'm fetching from the dictionary and I might not always have that knowledge.
I wouldn't mind if myValue were an inherited/abstract property (if there is such a thing), since every Variable will have a property named myValue (each will differ in type but not in name). In that case I guess I could make IVariable an abstract class rather than an interface, but then I still run into trouble as far as what to put for the type of myValue.
Could I do a cast of theVar into something using as by first checking its type with is? I'm not sure if that would work or is even possible.
I've looked at these posts for guidance (especially the second one):
Wildcard equivalent in C# generics
C# Generics: wildcards
However, my situation is still slightly different than the second example above because that example has an abstract method that is returning a void whereas I wish to have my variables return non-void generic values.
Thanks for any help.
C# has dynamic. You can create Dictionary<string, dynamic>
Or you can use object (boxing/unboxing) Dictionary<string, object>
Or you can get generic type from class
class MyClass<TDicValue>
{
Dictionary<strint, TDicValue> myDictionary;
}
I had this same problem where I had 20 slightly different types and I had to keep dictionaries on. I wanted to organize them in a list.
The problem was the same, selecting the right kind from the list with reflection or strings lacked the ability to provide a type to return to. #skrilmps answer is correct, but packing and and unpacking was at best unreliable without a lot (metric ton) of ugly messy code.
While unity does support dynamics in 2020, this doesn't exactly work with what i am doing unless I make like everything dynamic safe and that's shamble coding, not extensible or maintainable, and just sounds like a general nightmare.
I personally feel that I am an inadequate programmer after years of trying to learn and still not having my efforts provide a productive return or product of note, so i cannot claim the answer being mine, but in my research on the proper solution to this problem i found this: https://www.youtube.com/watch?v=A7qwuFnyIpM
In here he says basically if you add an interface to your similar classes that are intended for use in a variety of different lists, that you can instead make a list of that type of interface. I would assume dictionary as well, and then you can add any kind of class implementing this interface to this singular interface type defined list.
I tried using boxing/unboxing and came up with this solution. It appears to work... so far. But it doesn't seem very safe.
public interface Variable
{
object getValue();
void setValue(object value);
Type myType();
}
public class Variable<T>: Variable
{
private T myValue;
public object getValue()
{
return myValue;
}
public void setValue(object value)
{
myValue = (T)value;
}
public Type myType() { return myValue.GetType(); }
}
Dictionary<string, Variable> vars = new Dictionary<string, Variable>();
Variable<int> age = new Variable<int>();
age.setValue(21);
vars.Add("age", age);
Variable theAgeVar;
vars.TryGetValue("age", out theAgeVar);
Console.WriteLine("age = " + theAgeVar.getValue());
Variable<double> height = new Variable<double>();
height.setValue(5.9);
Variable theHeightVar;
vars.TryGetValue("age", out theHeightVar);
Debug.Log("height = " + theHeightVar.getValue());
This prints:
age = 21
height = 5.9
One thing I do not like is that I had to make the return type of getValue() be an object. If I wanted myValue (which is of type T) to implement IComparable, for instance, then this information is lost when the boxing happens and the caller receives an object.
// The following should resolve the boxing problem and now is totally generic:
public interface IVariable<T>
{
T GetContent();
void SetContent(T value);
Type GetDataType();
}
public class Variable<T> : IVariable
{
private T content;
public T GetContent()
{
return content;
}
public void SetContent(T value)
{
content = value;
}
public Type GetDataType() { return GetType(); }
}
Dictionary<string, Variable<T>> variables = new Dictionary<string, Variable<T>>();
An object can provide its binding semantics by implementing
IDynamicMetaObject Provider—or more easily by subclassing
DynamicObject, which provides a default implementation of this
interface.
source
I never implemented this interface nor class and always been able to execute things dynamically:
public class aa
{
public void bbb()
{ }
}
dynamic a = new aa().bbb();
so what do they mean by this quote ?
im trying to understand when should i need to use IDynamicMetaObject or the DynamicObject inheritance
The dynamic keyword causes references to an object to be late-bound and only resolved at runtime. Usually, the reason for this is because you are using an IDynamicMetaObjectProvider implementer, which allows your code to decide how to treat the run-time property resolution. That is, you may want to add and remove properties at runtime (typically implemented as a dictionary, like ExpandoObject).
What your example code is doing is just preventing compile-type type checking. In fact it's worse than doing nothing, because if you wrote code that accessed a nonexistent property or method of your class, it would still compile, but of course crash at runtime. I can't think of many good reasons to refer to concrete classes with dynamic (expect for squishy typecasting or duck-typing, but we usually use interfaces for stuff like this in C#!)
Example implementation of a dynamic object that inherits DynamicObject from one of my own projects:
https://github.com/jamietre/IQObjectMapper/blob/master/source/IQObjectMapper/IQDynamicObject.cs
(It makes one call to a factory method that returns a new dictionary with options, all you need to do to make this non-dependent is change the constructor from:
InnerDict = ObjectMapper.MapperCache.GetDictionary<object>(Options);
to:
InnerDict = new Dictionary<string,object>();
and get rid of a couple conditons that check options
I hate to give "pithy" answers like this, because its not very imformative, but this really is a case of "if you needed it, you would know."
It is very rare that you would need to implement a dynamic object in an application, or even most library code. The interface is meant for people implementing classes that can only be used as dynamic objects; for example, if you wanted to implement Javascript-like behavior on your object. You can call any property or method you want on such an object, and it will compile. It's up to your implementation at run-time to figure out whether a given call works or not.
A totally pointless but descriptive example would be a class that decides which properties are valid based on the day of the week:
public class WeekendObject : DynamicObject
{
Dictionary<string, object> propertybag = new Dictionary<string, object>();
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
{
if (name.StartsWith("Sunday"))
{
return propertybag.TryGetValue(name, out result);
}
}
else
{
if (!name.StartsWith("Sunday"))
{
return propertybag.TryGetValue(name, out result);
}
}
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
if (DateTime.Now.DayOfWeek == DayOfWeek.Sunday)
{
if (name.StartsWith("Sunday"))
{
propertybag[binder.Name.ToLower()] = value;
return true;
}
}
else
{
if (!name.StartsWith("Sunday"))
{
propertybag[binder.Name.ToLower()] = value;
return true;
}
}
return false;
}
}
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. =)
I have an object, MySession, that has a hashtable for storing arbitrary properties with arbitrary types. The relevant part of the object definition is:
public class MySession
{
private Hashtable _sessionVars;
///
/// Set and retrieve session variables ala the traditional session managers.
/// So, SessionObject["var1"] can be used to set or retrieve a value for var1.
///
/// Name of the variable to access.
/// An object that was stored in the session under key.
public object this[string key] {
get {
if (_sessionVars.ContainsKey(key)) {
return this._sessionVars[key];
}
return null;
}
set {
if (this._sessionVars.ContainsKey(key)) {
this._sessionVars.Remove(key);
}
this._sessionVars[key] = value;
}
}
}
The annoying thing is that I have to properly cast the properties when I want to use them. For example:
MySession session = new MySession();
if ( (bool)session["valid"] == true ) { /* do something fun */ }
I would rather be able to do:
MySession session = new MySession();
if ( session["valid"] == true ) { /* do something fun */ }
Is it possible to do this in C#? If so, how?
Update: I do not want to use explicit methods for accessing the properties. The point is to be able to access them as simply as possible. Not like session.GetProperty(name, type) or something.
If you think carefully, you will realize that this is inherently impossible.
What if you write session[someTextbox.Text]?
What if you assign two different types to the same identifier?
Compiling such code would involve solving the halting problem to figure out what type each string would have.
Instead, you could make a strongly-typed wrapper class around HttpContext.Current.Session with properties that include casts in their getters.
If you are using .Net Framework 4.0 then you can do it by deriving your MySession class from DynamicObject and overriding the necessary methods.
Here is the code:
public class MySession : DynamicObject
{
//Why not use Dictionary class?
private Hashtable _sessionVars = new Hashtable();
public override bool TrySetMember(SetMemberBinder binder, object value)
{
this[binder.Name] = value;
return true;
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
result = this[binder.Name];
return true;
}
//You can make it private so that users do not use strings directly.
public object this[string key]
{
get
{
if (_sessionVars.ContainsKey(key))
{
return this._sessionVars[key];
}
return null;
}
set
{
if (this._sessionVars.ContainsKey(key))
{
this._sessionVars.Remove(key);
}
this._sessionVars[key] = value;
}
}
}
And this how you use it:
dynamic ses = new MySession();
ses.number = 5;
ses.boolean = true;
Console.WriteLine(ses.number > 4);
if (ses.boolean)
{
Console.WriteLine(ses.number - 1);
}
Console.ReadKey();
No need for casting or using string to access the new fields! If you are using Resharper you will get intellisense for existing fields too. If you need more functionality you can override other members too.
I personally end up having to handle the scenario where the session variable hasn't been set yet. Therefore, I end up with a method that looks like this:
public class MySession
{
...
public T GetValue<T>(string key, T defaultValue)
{
return _sessionVars.ContainsKey(key) ? this._sessionVars[key] as T : defaultValue;
}
}
Then T can be inferred. It can then be called like this (no casting required):
if (mySession.GetValue("valid", false))
{
// fun stuff here
}
I'm not really sure is "as T" works. If not, you can cast it to (T) done that before. "as T" would be nice if you've got inherited classes and such.
I typically derive off a class like mySession and call base.GetValue() in property getters I expose off the derived class.
If you're passing string (or any sort of object) keys, then it's impossible to do; the indexer method can only return one specific type, so you couldn't possible have it return a string or a double, for instance.
There are a couple of options: one, if this is a limited-scope class that doesn't need the flexibility of arbitrary keys, then you can just add explicit properties--maybe just for commonly used properties if you want to still be able to fall back on the object-returning indexer.
Or, you could add a generic Get method, like so:
public T GetValue<T>(object key) {
if(_hashSet[key] is T) {
return (T)_hashSet[key];
}
throw new InvalidCastException();
}
That doesn't get you much, though, since you'll still have to specify the type name, you're just moving it from the cast to the generic parameter.
EDIT: Of course, how you want to handle invalid casts is up to you, but throwing the exception mimics the behavior of the direct cast. As someone mentioned in another answer, if you also specify a parameter of type T in the signature, then it will get the correct type from that parameter.
Easy and best way to add session
public static void Add<T>(string key, T value)
{
var current = HttpContext.Current;
if (current == null) return;
current.Session.Add(key, value);
}
Example
public Model User
{
private string searchText
{
get { return SessionHelper.Get<string>("searchText"); }
set { SessionHelper.Add("searchText", value); }
}
}
My question concerns c# and how to access Static members ... Well I don't really know how to explain it (which kind of is bad for a question isn't it?) I will just give you some sample code:
Class test<T>{
int method1(Obj Parameter1){
//in here I want to do something which I would explain as
T.TryParse(Parameter1);
//my problem is that it does not work ... I get an error.
//just to explain: if I declare test<int> (with type Integer)
//I want my sample code to call int.TryParse(). If it were String
//it should have been String.TryParse()
}
}
So thank you guys for your answers (By the way the question is: how would I solve this problem without getting an error). This probably quite an easy question for you!
Edit: Thank you all for your answers!
Though I think the try - catch phrase is the most elegant, I know from my experience with vb that it can really be a bummer. I used it once and it took about 30 minutes to run a program, which later on only took 2 minutes to compute just because I avoided try - catch.
This is why I chose the switch statement as the best answer. It makes the code more complicated but on the other hand I imagine it to be relatively fast and relatively easy to read. (Though I still think there should be a more elegant way ... maybe in the next language I learn)
Though if you have some other suggestion I am still waiting (and willing to participate)
The problem is that TryParse isn't defined on an interface or base class anywhere, so you can't make an assumption that the type passed into your class will have that function. Unless you can contrain T in some way, you'll run into this a lot.
Constraints on Type Parameters
Short answer, you can't.
Long answer, you can cheat:
public class Example
{
internal static class Support
{
private delegate bool GenericParser<T>(string s, out T o);
private static Dictionary<Type, object> parsers =
MakeStandardParsers();
private static Dictionary<Type, object> MakeStandardParsers()
{
Dictionary<Type, object> d = new Dictionary<Type, object>();
// You need to add an entry for every type you want to cope with.
d[typeof(int)] = new GenericParser<int>(int.TryParse);
d[typeof(long)] = new GenericParser<long>(long.TryParse);
d[typeof(float)] = new GenericParser<float>(float.TryParse);
return d;
}
public static bool TryParse<T>(string s, out T result)
{
return ((GenericParser<T>)parsers[typeof(T)])(s, out result);
}
}
public class Test<T>
{
public static T method1(string s)
{
T value;
bool success = Support.TryParse(s, out value);
return value;
}
}
public static void Main()
{
Console.WriteLine(Test<int>.method1("23"));
Console.WriteLine(Test<float>.method1("23.4"));
Console.WriteLine(Test<long>.method1("99999999999999"));
Console.ReadLine();
}
}
I made a static dictionary holding a delegate for the TryParse method of every type I might want to use. I then wrote a generic method to look up the dictionary and pass on the call to the appropriate delegate. Since every delegate has a different type, I just store them as object references and cast them back to the appropriate generic type when I retrieve them. Note that for the sake of a simple example I have omitted error checking, such as to check whether we have an entry in the dictionary for the given type.
To access a member of a specific class or interface you need to use the Where keyword and specify the interface or base class that has the method.
In the above instance TryParse does not come from an interface or base class, so what you are trying to do above is not possible. Best just use Convert.ChangeType and a try/catch statement.
class test<T>
{
T Method(object P)
{
try {
return (T)Convert.ChangeType(P, typeof(T));
} catch(Exception e) {
return null;
}
}
}
One more way to do it, this time some reflection in the mix:
static class Parser
{
public static bool TryParse<TType>( string str, out TType x )
{
// Get the type on that TryParse shall be called
Type objType = typeof( TType );
// Enumerate the methods of TType
foreach( MethodInfo mi in objType.GetMethods() )
{
if( mi.Name == "TryParse" )
{
// We found a TryParse method, check for the 2-parameter-signature
ParameterInfo[] pi = mi.GetParameters();
if( pi.Length == 2 ) // Find TryParse( String, TType )
{
// Build a parameter list for the call
object[] paramList = new object[2] { str, default( TType ) };
// Invoke the static method
object ret = objType.InvokeMember( "TryParse", BindingFlags.InvokeMethod, null, null, paramList );
// Get the output value from the parameter list
x = (TType)paramList[1];
return (bool)ret;
}
}
}
// Maybe we should throw an exception here, because we were unable to find the TryParse
// method; this is not just a unable-to-parse error.
x = default( TType );
return false;
}
}
The next step would be trying to implement
public static TRet CallStaticMethod<TRet>( object obj, string methodName, params object[] args );
With full parameter type matching etc.
This isn't really a solution, but in certain scenarios it could be a good alternative: We can pass an additional delegate to the generic method.
To clarify what I mean, let's use an example. Let's say we have some generic factory method, that should create an instance of T, and we want it to then call another method, for notification or additional initialization.
Consider the following simple class:
public class Example
{
// ...
public static void PostInitCallback(Example example)
{
// Do something with the object...
}
}
And the following static method:
public static T CreateAndInit<T>() where T : new()
{
var t = new T();
// Some initialization code...
return t;
}
So right now we would have to do:
var example = CreateAndInit<Example>();
Example.PostInitCallback(example);
However, we could change our method to take an additional delegate:
public delegate void PostInitCallback<T>(T t);
public static T CreateAndInit<T>(PostInitCallback<T> callback) where T : new()
{
var t = new T();
// Some initialization code...
callback(t);
return t;
}
And now we can change the call to:
var example = CreateAndInit<Example>(Example.PostInitCallback);
Obviously this is only useful in very specific scenarios. But this is the cleanest solution in the sense that we get compile time safety, there is no "hacking" involved, and the code is dead simple.
Do you mean to do something like this:
Class test<T>
{
T method1(object Parameter1){
if( Parameter1 is T )
{
T value = (T) Parameter1;
//do something with value
return value;
}
else
{
//Parameter1 is not a T
return default(T); //or throw exception
}
}
}
Unfortunately you can't check for the TryParse pattern as it is static - which unfortunately means that it isn't particularly well suited to generics.
The only way to do exactly what you're looking for would be to use reflection to check if the method exists for T.
Another option is to ensure that the object you send in is a convertible object by restraining the type to IConvertible (all primitive types implement IConvertible). This would allow you to convert your parameter to the given type very flexibly.
Class test<T>
{
int method1(IConvertible Parameter1){
IFormatProvider provider = System.Globalization.CultureInfo.CurrentCulture.GetFormat(typeof(T));
T temp = Parameter1.ToType(typeof(T), provider);
}
}
You could also do a variation on this by using an 'object' type instead like you had originally.
Class test<T>
{
int method1(object Parameter1){
if(Parameter1 is IConvertible) {
IFormatProvider provider = System.Globalization.CultureInfo.CurrentCulture.GetFormat(typeof(T));
T temp = Parameter1.ToType(typeof(T), provider);
} else {
// Do something else
}
}
}
Ok guys: Thanks for all the fish. Now with your answers and my research (especially the article on limiting generic types to primitives) I will present you my solution.
Class a<T>{
private void checkWetherTypeIsOK()
{
if (T is int || T is float //|| ... any other types you want to be allowed){
return true;
}
else {
throw new exception();
}
}
public static a(){
ccheckWetherTypeIsOK();
}
}
You probably cant do it.
First of all if it should be possible you would need a tighter bound on T so the typechecker could be sure that all possible substitutions for T actually had a static method called TryParse.
You may want to read my previous post on limiting generic types to primitives. This may give you some pointers in limiting the type that can be passed to the generic (since TypeParse is obviously only available to a set number of primitives ( string.TryParse obviously being the exception, which doesn't make sense).
Once you have more of a handle on the type, you can then work on trying to parse it. You may need a bit of an ugly switch in there (to call the correct TryParse ) but I think you can achieve the desired functionality.
If you need me to explain any of the above further, then please ask :)
Best code: restrict T to ValueType this way:
class test1<T> where T: struct
A "struct" here means a value type.
String is a class, not a value type.
int, float, Enums are all value types.
btw the compiler does not accept to call static methods or access static members on 'type parameters' like in the following example which will not compile :(
class MyStatic { public static int MyValue=0; }
class Test<T> where T: MyStatic
{
public void TheTest() { T.MyValue++; }
}
=> Error 1 'T' is a 'type parameter', which is not valid in the given context
SL.
That is not how statics work. You have to think of statics as sort of in a Global class even if they are are spread across a whole bunch of types. My recommendation is to make it a property inside the T instance that can access the necessary static method.
Also T is an actual instance of something, and just like any other instance you are not able to access the statics for that type, through the instantiated value. Here is an example of what to do:
class a {
static StaticMethod1 ()
virtual Method1 ()
}
class b : a {
override Method1 () return StaticMethod1()
}
class c : a {
override Method1 () return "XYZ"
}
class generic<T>
where T : a {
void DoSomething () T.Method1()
}