PDA

View Full Version : تبدیل رشته به نام متغیر یا تابع



Mo_hasan1366
پنج شنبه 25 خرداد 1391, 08:28 صبح
با عرض سلام و خسته نباشی

ایا کلاسی یا ابزاری برای تبدیل رشته به نام متغیر یا تابع وجود داره

با تشکر

Saeed_m_Farid
پنج شنبه 25 خرداد 1391, 11:07 صبح
با عرض علیک سلام و سلامت باشی
راستش من که معنی سوال رو نفهمیدم! میشه دقیق تر بگین چکار میخواین بکنین؟ مثلاً میخواین با داشتن یه String یه متد رو فراخوانی کنید؟ یا میخواین یه سازنده بدون پارامتر برای ساخت instance داشته باشین؟ آیا یه تابع بی نام یا Lambda Expression کارتون رو راه میاندازه؟
"متغیر یا تابع" از زمین تا آسمون فرق میکنه! تابع پارامتر ورودی، خروجی داره، انواع پیاده سازی ها و ...
برای متغیر راحت تر هست قضیه، میشه از System.Reflection (http://msdn.microsoft.com/en-us/library/system.reflection.aspx) استفاده کرد، این کار برای فراخوانی تابع با داشتن نامش هم صادقه ...
بیشتر توضیح بدین، جواب کاملتری میگیرین!

Mo_hasan1366
شنبه 27 خرداد 1391, 08:23 صبح
میخوام یک فایل Xml شامل اسم متغیر و یک فایل dll شامل کلاسها و توابع داشته باشم که داخل برنامه به وسیله اسم توابع که داخل Xml هست فراخوانیش کنم

Saeed_m_Farid
شنبه 27 خرداد 1391, 10:45 صبح
چون من ساختار Xml شما رو نمیدونم فرض رو براین میذارم که Element ها بصورت پشت سر هم قرار دارن، در اینصورت جواب شما یه چیزی مثل کد زیر میشه:

/// <summary>
/// Dynamically Invoke A Method, Pass multiple parameter(s) to the Called Method
/// Given Strings with Method Name, parameters and
/// Namespace + Class Name as typeNmae
/// </summary>
/// <param name="assemblyPath">
/// The path of assembly file to load
/// </param>
/// <param name="xmlPath">
/// A URI string referencing the file to load into a new System.Xml.Linq.XElement
/// </param>
/// <param name="typeName">
/// The full name of type, Usually contain TheNamespace.TheClass
/// </param>
/// <returns>
/// An object containing the return value of the invoked method, or null in the
/// case of a constructor.
/// </returns>
public object RunMethod(
string assemblyPath = "YourAssembly.dll",
string xmlPath = "Method.xml",
string typeName = "TheNamespace.TheClass")
{
try
{
Assembly assembly = Assembly.LoadFile(assemblyPath);
Type type = assembly.GetType(typeName);
XElement parent = XElement.Load(xmlPath);
string methodName = parent.Element("METHOD").Value;
if (type != null)
{
MethodInfo method = type.GetMethod(methodName);
object[] arguments = (from p in method.GetParameters()
let arg = parent.Element(p.Name)
where arg != null
select (object)arg.Value).ToArray();

if (arguments.Length != method.GetParameters().Length)
throw new ArgumentException("Parameters didn't match");

object classInstance = Activator.CreateInstance(type, null);
return method.Invoke(classInstance, arguments);
}
return null;
}
catch (Exception ex)
{
//LogError("Error:" + ex.Message);
throw;
}
}

توضیحات رو بطور کامل تو summery کد گذاشتم ولی بازم میگم که کارآیی این کد به میزان زیادی وابسته به ساختار xml شما داره، مثلاً چند تا تابع رو ساپورت نمیکنه، Case-sensitive هست، پارامترهاتون حتماً string هستن، ساختارهای تودرتو رو نمیتونه بخونه و ...، فقط برای xml ای با فرمت زیر جواب میده، اگه فرمت xml شما فرق میکنه باید این تابع رو با xml خودتون sync کنید:
<METHOD>TestMethod</METHOD>
<PARAM1>param1</PARAM1>
<PARAM2>param2</PARAM2>
...
<PARAM99>Saeed_m_Farid</PARAM99>
<PARAM100>Mo_hasan1366</PARAM100>

ضمناً برای استفاده از این تابع، شما لازمه اینا رو تو پروژه تون use کنید:
System.Reflection (http://msdn.microsoft.com/en-us/library/system.reflection.aspx)
System.Xml.Linq (http://msdn.microsoft.com/en-us/library/system.xml.linq.aspx)

Saeed_m_Farid
شنبه 27 خرداد 1391, 11:02 صبح
میخوام یک فایل Xml شامل اسم متغیر و یک فایل dll شامل کلاسها و توابع داشته باشم که داخل برنامه به وسیله اسم توابع که داخل Xml هست فراخوانیش کنم
اگه خودتون نام توابع و نام متغیرها رو از XML میخونین و تو این قسمت مشکلی ندارین، پس من با xml شما کاری ندارم و با این فرض که شما لیست متغیرها و مقادیرشون رو خودتون load کردین تو یه []object اونوقت این تابع بدرد میخوره :

/// <summary>
/// Dynamically Invoke A Method, Pass multiple parameter(s) to the Called Method
/// Given Strings with Method Name, parameters and
/// Namespace + Class Name as typeNmae
/// </summary>
/// <param name="parametersArray">
/// Parameters:
/// obj:
/// The object on which to invoke the method or constructor. If a method is static,
/// this argument is ignored. If a constructor is static, this argument must
/// be null or an instance of the class that defines the constructor.
///
/// parameters:
/// An argument list for the invoked method or constructor. This is an array
/// of objects with the same number, order, and type as the parameters of the
/// method or constructor to be invoked. If there are no parameters, parameters
/// should be null.If the method or constructor represented by this instance
/// takes a ref parameter (ByRef in Visual Basic), no special attribute is required
/// for that parameter in order to invoke the method or constructor using this
/// function. Any object in this array that is not explicitly initialized with
/// a value will contain the default value for that object type. For reference-type
/// elements, this value is null. For value-type elements, this value is 0, 0.0,
/// or false, depending on the specific element type.
/// </param>
/// <param name="methodName">
/// The System.String containing the name of the public method to get.
/// </param>
/// <param name="assemblyPath">
/// The path of assembly file to load
/// </param>
/// <param name="typeName">
/// The full name of type, Usually contain TheNamespace.TheClass
/// </param>
/// <returns>
/// An object containing the return value of the invoked method, or null in the
/// case of a constructor.
/// </returns>
public object RunMethod(
object[] parametersArray,
string methodName,
string assemblyPath = "YourAssembly.dll",
string typeName = "TheNamespace.TheClass")
{
try
{
Assembly assembly = Assembly.LoadFile(assemblyPath);
Type type = assembly.GetType(typeName);
if (type != null)
{
MethodInfo methodInfo = type.GetMethod(methodName);
if (methodInfo != null)
{
ParameterInfo[] parameters = methodInfo.GetParameters();
object classInstance = Activator.CreateInstance(type, null);
return methodInfo.Invoke(classInstance, parametersArray);
}
}
return null;
}
catch (Exception ex)
{
//LogError("Error:" + ex.Message);
throw;
}
}


ساختار parametersArray دقیقاً همونی هست که تو داکیومنت تابع Invoke (http://msdn.microsoft.com/en-us/library/a89hcwhh.aspx) اومده و من نقل قول کردم ...