mardi 1 septembre 2015

Using a type obtained through reflection in a data structure?

I have a class FutureClass that exists in .NET 4.6, but I'd like to be able to use it in an older codebase that builds with .NET 4.0. I can obtain and call FutureClass objects, but I want to store them in, say, a Dictionary<string, FutureClass>.

I've tried the following:

Dictionary<string, FutureClass> dict = new Dictionary<string, FutureClass>(); // didn't expect it to work

and

Type futureClassType = [...] //dynamically load the type from the assembly compiled with .NET 4.6
Dictionary<string, futureClassType> dict = new Dictionary<string, futureClassType>(); // held some promise, I thought

Is there a way to do what I'm trying? Thanks!





Test whether virtual method has been overridden

I know this is a bad idea, but I have a base class with a lot of virtual methods A(), B(), C() and a set of matching getters bool SupportsA(), bool supportsB(), ...

The idea is that implementers will only want to provide functionality for a small minority of virtual methods and I'd like to relieve them of the responsibility to also override the associated getter. Is there a way to tell from the base class whether any of the (potentially more than one) subclasses has overridden a specific method? Note these classes may be defined in different assemblies so I do not know the Type.

public class
{
  public bool SupportsA
  {
    get { return (A == overridden); }
  }
  public virtual void A()
  {
    // Null default implementation.
  }
}

There are some similar questions already, but they seem to assume that both the base type and the derived type are known at compile time.





Assigning a value to a dynamic type using reflection and bypassing the object cast\box that GetValue returns

I have two objects that have exactly the same properties. Here's an example:

public class Field<T>
{
   public T Value {get;set;}
   // more things
}

public class MainObject
{
   public string MyStr {get;set;}
   public int? MyInt {get;set;}
   public bool? MyBool {get;set;}
}

public class MainObjectField
{
   public Field<string> MyStr {get;set;}
   public Field<int?> MyInt {get;set;}
   public Field<bool?> MyBool {get;set;}
}

I have a task to create an instance of MainObjectField based on xpath instructions that I get from an external source.
I need to fetch the Value from the MainObject's instance as a part of the task.

Since I don't know about the type of the current property in compile type, I'm using a dynamic variable.

Here's a short example about how the code looks like in a high level aspect:

dynamic currentField = GetMainObjectsCurrentFieldSomehow();
object val = GetValFromMainObject(); // using reflection
currentField.Value = val; // I get an exception here

Now I'm getting this exception:

Cannot implicitly convert type 'object' to 'bool?'. An explicit conversion exists (are you missing a cast?)

I understand why I'm getting the exception and I'm trying to find a workaround.

I know that the currentField.Value and the val value are suppose to be the same type.

My problem is that using reflection (GetValue returns an object) automatically casts\boxes the value into an object and ruins my plans. I can't cast to the "correct" value since I know the types only in runtime.

How can I work this around?





c# Get Class Propertiy List With String Value

I have a class following message.I need get property list from here of runtime with string.For exmaple

var classObject = System.Reflection.Assembly.GetExecutingAssembly().CreateInstance("edifactProdat.PRODAT");
var unhTypeNames = classObject.GetType().GetProperty("UNH").GetType().GetProperties();

But this code not return my UNH object properties,its return all properties.

Pls help

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace edifactProdat
{
    public class PRODAT
    {
        public UNH UNH { get; set; }
        public BGM BGM { get; set; }
        public DTM DTM { get; set; }
        public NAD NAD { get; set; }
    }

    public class UNH
    {
        public string MessageReferenceNumber { get; set; }
        public string MessageTypeIdentifier { get; set; }
        public string MessageTypeVersionNumber { get; set; }
        public string MessageTypeReleaseNumber { get; set; }
        public string ControllingAgency { get; set; }
        public string AssociationAssignedCode { get; set; }
    }

    public class BGM
    {
        public string DocumentMessageNameCoded { get; set; }
        public string CodeListQualifier { get; set; }
        public string CodeListResponsibleAgencyCoded { get; set; }
        public string DocumentMessageNumber { get; set; }
        public string MessageFunctionCoded { get; set; }
    }

    public class DTM
    {
        public string DateTimePeriodQualifier { get; set; }
        public string DateTimePeriod { get; set; }
        public string DateTimePeriodFormatQualifier { get; set; }
    }

    public class NAD
    {
        public string PartyQualifier { get; set; }
        public string PartyIdIdentification { get; set; }
        public string CodeListQualifier { get; set; }
        public string CodeListResponsibleAgencyCoded { get; set; }
    }
}





C# Reflection - Get value of unknown field

I am trying to use reflection to call a method with some arguments but I have some difficulties to use the correct setup. Here what I've done.

// The method I am trying to call
// UnityGUI
// internal static float DoFloatField(EditorGUI.RecycledTextEditor editor, Rect position, Rect dragHotZone, int id, float value, string formatString, GUIStyle style, bool draggable)
// Called this way : EditorGUI.DoFloatField(EditorGUI.s_RecycledEditor, position, new Rect(0f, 0f, 0f, 0f), controlID, value, EditorGUI.kFloatFieldFormatString, style, false);

Type    editorGUIType = typeof(EditorGUI);
Type    RecycledTextEditorType = Assembly.GetAssembly(editorGUIType).GetType("UnityEditor.EditorGUI+RecycledTextEditor");
Type[]  argumentTypes = new Type[] { RecycledTextEditorType, typeof(Rect), typeof(Rect), typeof(int), typeof(float), typeof(string), typeof(GUIStyle), typeof(bool) };
MethodInfo doFloatFieldMethod = editorGUIType.GetMethod("DoFloatField", BindingFlags.NonPublic | BindingFlags.Static, null, argumentTypes, null);

// Here is the invoke part but I don't know how I can access to the s_RecycledEditor variable of type EditorGUI.RecycledTextEditor

FieldInfo fieldInfo = editorGUIType.GetField("s_RecycledEditor"); // This is null...
object o = fieldInfo.GetValue(null); // ... So the next part can't work.
object[] parameters = new object[]{ o, position2, position, controlID, controlID, "g7", style, true };
doFloatFieldMethod.Invoke(null, parameters);

I don't know how can I get the s_RecycledEditor value and if next of the code is working. I also don't know if I should use PropertyInfo or FieldInfo.

Thank you.

Edit : I forgot to add the description of the s_RecycledTextEditor.

internal static EditorGUI.RecycledTextEditor s_RecycledEditor = new EditorGUI.RecycledTextEditor();





Unable to cast object of type 'System.Reflection.RuntimeConstructorInfo' to type 'System.Reflection.MethodInfo'

I am using Dynamic LINQ in an ASP.NET MVC project to create queries at runtime.

First I create a string from client's request like this:

string predicate = GetPredicateString(request);

The predicate would have a value like "AvailableFrom = DateTime(2015, 10, 05)"

Then in my code I call ParseLambda method of DynamicLinq.DynamicExpression class like below.

var lambda = DynamicExpression.ParseLambda(typeof(Product), typeof(bool), predicate)

Doing so I receive the following exception:

Unable to cast object of type 'System.Reflection.RuntimeConstructorInfo' to type 'System.Reflection.MethodInfo'.

Line 1958: int FindBestMethod(IEnumerable<MethodBase> methods, Expression[] args, out MethodBase method){
Line 1959: MethodData[] applicable =
               methods
                   .Select(m => new MethodData
                   { 
                       MethodBase = m,
                       Parameters = m.GetParameters()
                           .Where(p => p.ParameterType != (MethodInfo)m).ReturnType).ToArray()
                   })
                   .Where(m => IsApplicable(m,args)).ToArray();

this part of the above fragment must be throwing the exception:

(MethodInfo)m)

I have tried to pass arguments matching other constructor overloads of DateTime structure, but it doesn't make any difference. So one can rule out passing invalid arguments being the cause.

I have to say that I am getting this exception only with DateTime and all other data types (string, int etc.) cause no problem.

I haven't found anything similar in the Internet, so I guess either I am doing something wrong or this is a very rare situation.

Any idea on how to resolve this issue would be greatly appreciated.





Casting object to generic type in order to use IEnumerable.Where

I'm trying to implement some filtering in my Dynamic Data + EF website and I'm using a QueryExtender with a CustomExpression. In the OnQuerying event of the CustomExpression I have access to e.Query(where e is of type CustomExpressionEventArgs) which is the Query that is used to get the data from the database. In order to filter the data I need to make changes to this query.

Now this query is of type System.Data.Objects.ObjectQuery<T>, where T is only known at runtime. I'm going to assume that whatever type T is, it's going to have a property called GameId. What I need to do is do a simple Where LINQ statement on this collection where I filter by that property.

short GameId = Convert.ToInt16(Session["GlobalGameFilter"]);
Type currentType = e.Query.ElementType;
//ObjectQuery implements IQueryable and I want to cast to ObjectQuery<CurrentType> 
MethodInfo method = typeof(Queryable).GetMethod("Cast").MakeGenericMethod(new Type[] { currentType });
var castedQuery = method.Invoke(e.Query, new object[]{e.Query});

This works, now castedQuery is of type ObjectQuery<currentType>

The problem is that in order to use castedQuery.Where() I need to cast it to an IEnumerable<currentType>, I can't just cast it to the non-generic IEnumerable.

I tried calling Where via reflection (from here):

var whereMethods = typeof(System.Linq.Enumerable)
.GetMethods(BindingFlags.Static | BindingFlags.Public)
.Where(mi => mi.Name == "Where");
MethodInfo whereMethod = null;
foreach (var methodInfo in whereMethods)
{
    var paramType = methodInfo.GetParameters()[1].ParameterType;
    if (paramType.GetGenericArguments().Count() == 2)
    {
        whereMethod = methodInfo;
    }
}

whereMethod = whereMethod.MakeGenericMethod(currentType);

var ret = whereMethod.Invoke(castedQuery, new object[] { castedQuery, BuildEqFuncFor<Placement>("GameId", GameId) });

But ret is always an empty collection.