I have a method with parameter as object, the object is a string value of properties in DocumentModel class
private PropertyInfo SortingListView(object obj)
{
return typeof(DocumentModel).GetProperty(obj.ToString());
}
I want the PropertyInfo to be used in a lambda expression like below:
var SortedDocuments=Documents.OrderByDescending(x => SortingListView(obj));
But it's not working. Any suggestions? Or any better way? Am I doing it correctly? Please help.
If I got it right, you're trying to sort your list of DocumentModel by whatever property is passed. The way you're currently doing it is wrong because you're actually sorting them by PropertyInfo of your property and since all objects are of the same type this basically does nothing. What you need to do actually is something like this:
private object SortingListView<T>(T obj, string propertyName)
{
return typeof(T).GetProperty(propertyName).GetValue(obj);
}
You can call it this way:
var obj = "SomePropertyName";
var sortedDocuments = Documents.OrderByDescending(x => SortingListView(x, obj));
If you're only going to use it here, you could also do it like this:
var obj = "SomePropertyName";
var sortedDocuments = Documents.OrderByDescending(x =>
typeof(DocumentModel).GetProperty(obj).GetValue(x));
This way you don't need extra method, you have all the logic inside your lambda expression.
Related
I'm trying to build some dynamic queries for my underlying database using LinqKit and the expandable-extensions.
In my code I have a property which looks like
private Expression<Func<MyModel, MyConfig, MyResult>> Parent
{
get
{
var modelParam = Expression.Parameter(typeof(MyModel), "myModel");
var configParam = Expression.Parameter(typeof(MyConfig), "config");
var conditionalExpression = Expression.Call(configParam, typeof(MyConfig).GetMethod("ShowParent"), Expression.Constant("SomeName"));
// how to decide whether to return an expression or null?
// build expression or return constant null-expression
}
}
which I call Parent.Invoke(myModel, config).
Is there any chance to gain access to the config-param which is passed to the Invoke-call to determine inside the getter whether to return a real Expression or just null?
The MyConfig class has a method bool ShowParent(string parentName) which I would like to call inside the getter to determine what to do?
Is this possible that way? If not, are there any good points where to start with?
want to do something very simple and that is getting the attribute of a property. Now I know how to do this via PropertyInfo etc but I know the property I want to get the attribute of so is it possible to do something like:
MyAttribute attr = (MyAttribute)customer.Forename;
Ideally want to avoid reflection. Only way I can think of is doing a linq statement like:
PropertyInfo pi = typeof(Customer).GetProperties().Where(x => x.Name == "Forename").FirstOrDefault();
MyAttribute attri = (MyAttribute)Attribute.GetCustomAttribute(pi, typeof(MyAttribute));
Don't like this as I am having to do a string comparison on the property name :(
Considering I know the property I want to get the attribute of I thought there might be an easier way?
Kzu wrote a piece of code to allow strongly typed reflection.
See a blog post here: http://blogs.clariusconsulting.net/kzu/linq-beyond-queries-strong-typed-reflection/
You can now get it as a NuGet package (NETFx Reflector):
http://nuget.org/packages/netfx-Reflector
// Void static method
MethodInfo cw = Reflect.GetMethod(() => Console.WriteLine);
// Instance void method
MethodInfo mi = Reflect<IView>.GetMethod(v => v.Show);
// Boolean returning instance method
MethodInfo pi = Reflect<IViewModel>.GetMethod<bool>(v => v.Save);
I have a method in Base class which calls ( by reflection to another method).
type.InvokeMember(context.Request["MethodName"],
System.Reflection.BindingFlags.InvokeMethod | System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance,
null,
this,
new object[] { context, Jobj }); // jObj is dynamic
jObj parameter type is dynamic ( can't change this type).
if the MethodName string value is : "getFinanceDetails" so that method is called..
void getFinanceDetails(object contextObj, dynamic obj)
{
//Here I need to do obj["Inv_num"].ToString().Decrpyt() ( my extension method).
//but it goes Bang cause I cant use extension method for dynamic.
//But I cant also send it decrypted from base cause not all values are encrpyrted.
}
However - I did solve it by using (inside the method):
((object) obj["Inv_num"]).ToString().Decrypt();
But I dont want to cast every time to object , just to enable extension method.
Is there anything I can do with the param type sending to fix it ?
my desire :
I want to be able to do : obj.ToString().Decrpyt() obj["Inv_num"].ToString().Decrpyt()
edit
public static string Decrypt(this string obj)
{
Func<string, string> Decrypt = Encryptions.GetDecryptedCode;
return Decrypt(obj);
}
obj ( in this case is IDictionary<string , object>) .
so I should be able to read properties. (inv_num in this sample.
Probably not exactly the syntax you were looking for but you could call the extension method as a simple static method on the dynamic object:
void getFinanceDetails(object contextObj, dynamic obj)
{
var decryptedValue = MyExtensions.Decrypt(obj);
}
This obviously assumes that at runtime obj is of the correct type that your extension method operates on. In your question you have shown some obj["Inv_num"] as if obj was a complex type with a property called Inv_num which is of type string. So you might need to adjust the call on the proper type:
var decryptedValue = MyExtensions.Decrypt(obj["Inv_num"]);
Assuming obj["Inv_num"].ToString() already returns the right value, you could easily do it in two steps:
string text = obj["Inv_num"].ToString();
var decrypted = text.Decrypt();
To be honest, it's not clear why getFinanceDetails (which should be changed to follow .NET naming conventions) can't be written as:
void getFinanceDetails(object contextObj, IDictionary<string, object> obj)
{
var decrypted = obj["Inv_num"].ToString().Decrypt();
}
Do you ever need to call it with something that doesn't implement IDictionary<string, object>?
I have the following loop over a dictionary type collection
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
}
I want to access the object properties, but the expected syntax doesn't work. E.G:
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
Object ob = entry.Value;
ob.property;
}
Fails because C# can't find the property wanted.
So, how do I access the desired properties?
solution:
foreach(KeyValuePair<Vector2, Object> entry in v_map.map_set)
{
if (entry.Value is warehouse)
{
warehouse ob = (warehouse)entry.Value;
}
}
If you know the type of the objects that are in the KeyValuePair, you can cast it to that type, and you will be able to find the properties you need.
And if you have several different objects stored, you can check which type it is by using is.
Like so:
if(entry.Value is Foo)
{
Foo lFoo = (Foo)entry.Value;
}
else if(entry.Value is Bar)
{
Bar lBar = (Bar)entry.Value;
}
You can make use of Refection to get the value of proerty of the object.
something like this
PropertyInfo info2 = object.GetType().GetProperty("prpertyname");
Object val = info2.GetValue(object, null);
You need to cast entry.Value to the type you need. The Object type itself isn't going to expose the properties you want.
If you just need to access the values, and you know the expected type you can use
foreach(ExpectedType value in v_map.map_set.Values.OfType<ExpectedType>())
{
var property = value.Property;
}
where Property is a property on ExpectedType.
The problem is that you're using an object which isn't typed. So you're going to need to use reflection like this:
PropertyInfo pi = ob.GetType().GetProperty("PropertyName");
var val = pi.GetValue(ob, null);
Now, if the property isn't public then you'll need to employ something else like this:
PropertyInfo pi = ob.GetType().GetProperty("PropertyName", BindingFlags.Instance | BindingFlags.NonPublic);
var val = pi.GetValue(ob, null);
Now, if this is actually a field you're trying to get to, you're going to need to do something different even yet:
FieldInfo fi = ob.GetType().GetField("fieldName");
var val = fi.GetValue(ob);
GetProperty method
BindingFlags enumeration
GetField method
Could someone please help me to understand how to get all parameters passed to delegate inside delegate itself?
I have class :
public class ShopManager : ShopEntities
{
public ShopManager getWhere(Func<Object, Object> dataList)
{
var x = dataList.???; // how to get arguments?
return this;
}
public Object getLike(Object dataValue)
{
return dataValue;
}
}
Then i call it as :
ShopManager shopManager = new ShopManager()
var demo = shopManager.getWhere(xxx => shopManager.getLike("DATA"));
The question is : how to get passed parameters "xxx" and "DATA" inside method getWhere()?
Thanks in advance.
You can't because it's the other way around. You can't get the arguments because the delegate does not hold them; the getWhere method will need to pass a value for the xxx parameter when invoking the delegate. The anonymous method that the delegate refers to will then receive this value as the xxx parameter, and in turn pass the string "DATA" as argument for the dataValue parameter when calling getLike. The argument values as such are not part of the delegate's state.
If you want to get information about the parameters as such (not their values), you can do that:
// get an array of ParameterInfo objects
var parameters = dataList.Method.GetParameters();
Console.WriteLine(parameters[0].Name); // prints "xxx"
If you use:
public ShopManager getWhere(Expression<Func<Object, Object>> dataList)
then you can divide the Expression into its subexpressions and parse them. But I'm not sure if using a delegate like you do is even the right thing.
You can't do it (easily). But I don't understand your idea. For what reason do you need to look into a dataList? This is just an anonymous method, you can call it and get results, you shouldn't need to examine or modify it at all.
What is your idea? Why not just call shopManager.getLike() ?
you can get the name of function by doing something like below.
var x = dataList.GetInvocationList().FirstOrDefault().Method.GetParameters();
sring name = x.FirstOrDefault().Name
this will print name as 'xxx'
Arguments are what you will provide while invoking the delegate via dataList(args), and not by the recipient of the invocation. If you want to provide additional information to getWhere() , you can try the following ....
public ShopManager getWhere(Func<Object, Object> dataList, params object[] additonalData)
{
// inspect the additionalData
}
Thanks for replies guys, i decided to use Expression> instead of common delegate. This allows to get both sides of expression - LHS and RHS.
For those who are interested in answer, this is it :
http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/0f6ca823-dbe6-4eb6-9dd4-6ee895fd07b5?prof=required
Thanks for patience and attention.
public static List<object> GetMethodParameterValues(Delegate method)
{
var target = method.Target;
if (target == null) return null;
var fields = target.GetType().GetFields();
var valueList = fields.Select(field => field.GetValue(target)).ToList();
return valueList;
}