|
|
Hi I'd like to run a method of a class calling it using its name in string format. Is it possible using reflection??
Thanks a lot
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Reflection;
namespace testMenu
{
class Program
{
static void Main(string[] args)
{
Type r = typeof(MyClass);
r.InvokeMember('a',null,null,ob....).
}
}
class MyClass
{
public static void a()
{
Console.WriteLine("Have good time");
}
}
|
|
|
|
|
TheGermoz wrote: Is it possible using reflection?
As stated no.
A method belongs to a class.
The class belongs to a namespace.
A class belongs to an assembly.
You must at least know about class/namespace/assembly to call a method.
If the class is in another assembly then you must load the assembly.
Then you must properly access the method.
|
|
|
|
|
False – the question has access to the class he wants to look up in and once you've got the Type then you can use reflection on it.
|
|
|
|
|
BobJanova wrote:
False – the question has access to the class he
wants to look up in and once you've got the Type then you can use reflection on
it.
I was wondering what the 1 votes were about....
So tell me - exactly how often have you found it useful to invoke a method of class within the same class?
Myself I would just call the method.
I answered the question for the cases that are actually useful.
|
|
|
|
|
You answered a question which wasn't the one that was actually asked, in a way which is likely to confuse the questioner.
Reflection is rarely useful full stop in my work, apart from loading types in from assemblies for plugins (which conform to a static interface so I don't use reflection for method lookups at all). The only place where I can see method lookups being useful is if you're trying to implement a scripting language or similar, at which point I can definitely see it being a case of looking up a method by name inside a (statically) known class (e.g. typeof(SomeClass)).
|
|
|
|
|
BobJanova wrote: if you're trying to implement a scripting language
If I was doing a script language I would compile it before interpreting it and thus the linkage would still be explicit rather than dynamic.
|
|
|
|
|
public void InvokeAMethod(string name, string arg)
{
var type = this.GetType();
var method = type.GetMethod(name);
method.Invoke(this, new object[] { arg });
}
public void aMethod(string test)
{
Console.WriteLine(test);
}
|
|
|
|
|
|
Not really. It was Microsoft's implementation of Reflection that was brilliant
|
|
|
|
|
Bear in mind that reflection is slow; you shouldn't use it unless you don't know what you want to run at compile time (e.g. you are running commands based on user input, or you do not have a compile time reference to the class or a relevant interface through which to bind statically).
|
|
|
|
|
I have a simple WCF service with one interface and one class. When I add a service reference to my console apps, my WCF service class is not getting the expected name. My WCF service class name is service1 but it is exposed to the client end as Service1Client.
Why is the word "Client" being added before my actual class name? Do I need to add anything in my web.config for the service or in the app.config for the console end?
tbhattacharjee
|
|
|
|
|
This is not a C# question, it would be better posted in the WCF forum.
One of these days I'm going to think of a really clever signature.
|
|
|
|
|
Tridip Bhattacharjee wrote: Why is the word "Client" being added before my actual class name? You can select any class name you want in the Add Service Reference dialog.
/ravi
|
|
|
|
|
really i just do not understand what u trying to say. where we add service then we have to give service reference name. i gave service reference name say myfirstservice but when i type myfirstservice and dot then my class name is not appearing like "Myservice" rather a class name appear called "Myserviceclient" why the word "client" is being added before my actual class name and expose to client end.
tbhattacharjee
|
|
|
|
|
My apologies Tridip, I read your question too hastily.
/ravi
|
|
|
|
|
anyway no prob.....thanks
tbhattacharjee
|
|
|
|
|
I would verify your WCF Service Project Name and/or your Namespaces. Also, in the rare case that you renamed the WCF Service Project, I've found it's wise to just start over (i.e. delete the project and create a brand new one with the name you want) vs. figuring out all the things you need to also rename behind the scenes.
Russ
|
|
|
|
|
Hi
I'm trying to build a program which will read and assign to variables the values from an XML file which goes like this (without the *):
<*n1> random number here <*/n1>
<*n2> random number here <*/n2>
I tried to use the XmlTextReader but I got an error when I passed the location of the file
("C:\\Documents and Settings\\myfile.xml") so I tried the XmlDocument and it's function SelectSingleNode("n1") but I got another error.
So what's the best way to get the values from this XML file? (I also want to show an error message if the XML file is not built as I mentioned (<*n1> <*/n1> <*n2> <*/n2>).
thanks
|
|
|
|
|
gibsray wrote: but I got an error when I passed the location of the file
I tried the XmlDocument and it's function SelectSingleNode("n1") but I got another error. We can't read your mind. What errors did you receive?
/ravi
|
|
|
|
|
I very much doubt that your file is in the root of the Document and Settings folder. Perhaps you should double check that your path is valid.
I wasn't, now I am, then I won't be anymore.
|
|
|
|
|
You need a root. You did not provide the error, so so not know what the exact issue is, but can only have one root node.
<items>
<*n1>random number here </*n1>
<*n2>random number here </*n2>
</items>
Of course this is not good xml either. XML will object to the *, and there is no * before the backslash.
|
|
|
|
|
|
I have this code:
public static IQueryable<T> OrderBy<T>(
this IQueryable<T> source, string propertyName, string order)
{
var type = typeof(T);
var asc = order == "asc" ? true:false;
string methodName = asc ? "OrderBy" : "OrderByDescending";
var parameter = Expression.Parameter(type, "p");
var property = type.GetProperty(propertyName);
var propertyAccess = Expression.MakeMemberAccess(parameter, property);
var orderByExp = Expression.Lambda(propertyAccess, parameter);
MethodCallExpression resultExp = Expression.Call(typeof(Queryable), methodName,
new Type[] { type, property.PropertyType },
source.Expression, Expression.Quote(orderByExp));
return source.Provider.CreateQuery<T>(resultExp);
}
And i would like to extend it to allow child properties, like "Address.Street"
if i pass just a simple property it works nice... but i want to make it better and accept child object property to make order by.
Anyone knows how to modify it?
I tryed but no success... i don't know how to make it to find the child object property and create the MemberAccess with it
Thanks!!
|
|
|
|
|
There you go, sorts on properties of properties... not quite sure if it works with methods. The logic is there, but it's not fully tested
public static IEnumerable<T> SortObject<T>(this IEnumerable<T> ObjectToSort, string SortBy)
{
if (ObjectToSort == null)
return null;
if (string.IsNullOrEmpty(SortBy) == true)
return null;
string[] tempSorts = SortBy.Split(',');
List<string> SortList = new List<string>();
bool inParanthese = false;
string addString = string.Empty;
foreach (string tempSort in tempSorts)
{
if ((tempSort.Contains("(") == true) && (tempSort.Contains(")") == false))
{
inParanthese = true;
}
else if (tempSort.Contains(")") == true)
{
inParanthese = false;
}
if (inParanthese == false)
{
if (string.IsNullOrEmpty(addString) == false)
{
SortList.Add(addString + "," + tempSort.Trim());
}
else
{
SortList.Add(tempSort);
}
addString = string.Empty;
}
else
{
if (string.IsNullOrEmpty(addString) == false)
addString += ",";
addString += tempSort.Trim();
}
}
string[] Sorts = SortList.ToArray();
bool Sorted = false;
foreach (string FieldSort in Sorts)
{
string[] SubSort = FieldSort.Trim().Split(' ');
string[] props = SubSort[0].Split('.');
Type type = typeof(T);
ParameterExpression arg = Expression.Parameter(type, "x");
Expression expr = arg;
foreach (string prop in props)
{
System.Reflection.PropertyInfo pi = type.GetProperty(prop);
if (pi != null)
{
Sorted = true;
expr = Expression.MakeMemberAccess(expr, pi);
type = pi.PropertyType;
}
else
{
string wholeMethod = prop;
if ((wholeMethod.Contains("(") == false) && (wholeMethod.Contains(")") == false))
{
wholeMethod += "()";
}
int firstParans = wholeMethod.IndexOf('(');
int lastParans = wholeMethod.LastIndexOf(')');
if ((firstParans > -1) && (lastParans > firstParans))
{
string methodname = wholeMethod.Substring(0, firstParans).Trim();
string paramList = wholeMethod.Substring(firstParans + 1, lastParans - (firstParans + 1));
System.Reflection.MethodInfo mi = null;
List<string> indParams = null;
if (paramList.Length > 0)
{
bool inDoubleQuotes = false;
bool inSingleQuotes = false;
string currParam = string.Empty;
indParams = new List<string>();
foreach (char c in paramList)
{
if (c == '\"')
{
if (inSingleQuotes == false)
{
inDoubleQuotes = !inDoubleQuotes;
}
currParam += c;
}
else if (c == '\'')
{
if (inDoubleQuotes == false)
{
inSingleQuotes = !inSingleQuotes;
}
currParam += c;
}
else if ((c == ',') && (inDoubleQuotes == false) && (inSingleQuotes == false))
{
if (string.IsNullOrEmpty(currParam) == false)
{
indParams.Add(currParam);
currParam = string.Empty;
}
}
else
{
currParam += c;
}
}
if ((string.IsNullOrEmpty(currParam) == false) && (inDoubleQuotes == false) &&
(inSingleQuotes == false))
{
indParams.Add(currParam);
}
Type[] methodTypes = new Type[indParams.Count];
Expression[] methodParams = new Expression[indParams.Count];
int paramTypeIndex = 0;
int intResult;
foreach (string indParam in indParams)
{
if (indParam[0] == '\'')
{
if ((indParam.Length == 3) && (indParam[2] == '\''))
{
methodTypes[paramTypeIndex] = typeof(char);
methodParams[paramTypeIndex] = Expression.Constant(indParam[1], typeof(char));
}
else
{
methodTypes[paramTypeIndex] = typeof(string);
methodParams[paramTypeIndex] = Expression.Constant(indParam, typeof(string));
}
}
else if (indParam[0] == '"')
{
methodTypes[paramTypeIndex] = typeof(string);
methodParams[paramTypeIndex] = Expression.Constant(indParam, typeof(string));
}
else if (int.TryParse(indParam, out intResult) == true)
{
methodTypes[paramTypeIndex] = typeof(int);
methodParams[paramTypeIndex] = Expression.Constant(intResult, typeof(int));
}
else
{
methodTypes[paramTypeIndex] = typeof(object);
methodParams[paramTypeIndex] = Expression.Constant(indParam);
}
paramTypeIndex++;
}
mi = type.GetMethod(methodname, methodTypes);
if (mi != null)
{
expr = Expression.Call(expr, mi, methodParams);
}
}
else
{
mi = type.GetMethod(methodname, System.Type.EmptyTypes);
if (mi != null)
{
expr = Expression.Call(expr, mi);
}
}
}
}
}
LambdaExpression lambda = Expression.Lambda(expr, arg);
if (Sorted == true)
{
IQueryable<T> queryableData = ObjectToSort.AsQueryable<T>();
if ((SubSort.Count() > 1) && (string.Compare(SubSort[1].Trim(), "desc", true) == 0))
{
MethodCallExpression MyExpr = Expression.Call(
typeof(Queryable), "OrderByDescending",
new Type[] { typeof(T), type },
queryableData.Expression, lambda);
IQueryable<T> results = queryableData.Provider.CreateQuery<T>(MyExpr);
try
{
results.Count();
ObjectToSort = results;
}
catch (Exception exc){}
}
else
{
MethodCallExpression MyExpr = Expression.Call(
typeof(Queryable), "OrderBy",
new Type[] { typeof(T), type },
queryableData.Expression, Expression.Quote(lambda));
IQueryable<T> results = queryableData.Provider.CreateQuery<T>(MyExpr);
try
{
results.Count();
ObjectToSort = results;
}
catch (Exception exc){}
}
}
}
if (Sorted == true)
{
return ObjectToSort;
}
else
{
return null;
}
}
|
|
|
|