පරාවර්තනය භාවිතා කරමින් නූල් වලින් දේපල වටිනාකම ලබා ගන්න


956

මගේ කේතයේ පරාවර්තනය 1 උදාහරණය භාවිතා කරමින් දත්ත පරිවර්තනය ක්‍රියාත්මක කිරීමට මම උත්සාහ කරමි.

මෙම GetSourceValueඋත්සවය විවිධ වර්ගයේ සංසන්දනය මාරු කර, නමුත් මම මේ ආකාරයේ ගුණ සහ ඉවත් කිරීමට හා ඇති අවශ්ය GetSourceValueපරාමිති ලෙස පමණක් තනි string භාවිතා දේපල වටිනාකම ලබා ගන්න. මට අවශ්‍ය වන්නේ පන්තියක් සහ දේපලක් නූල්වල තබා දේපලෙහි වටිනාකම නිරාකරණය කිරීමයි.

මෙය කළ හැකිද?

1 මුල් බ්ලොග් වෙබ් සංරක්ෂිත අනුවාදය

Answers:


1853
 public static object GetPropValue(object src, string propName)
 {
     return src.GetType().GetProperty(propName).GetValue(src, null);
 }

ඇත්ත වශයෙන්ම, ඔබට වලංගුකරණය සහ වොට්නොට් එක් කිරීමට අවශ්‍ය වනු ඇත, නමුත් එය එහි සාරාංශයයි.


11
ලස්සන හා සරලයි! මම එය සාමාන්‍ය දෙයක් බවට පත් කරමි:public static T GetPropertyValue<T>(object obj, string propName) { return (T)obj.GetType().GetProperty(propName).GetValue(obj, null); }
ඔහාඩ් ෂ්නයිඩර්

4
ප්‍රශස්තිකරණය මඟින් මේ ආකාරයට ශුන්‍ය ව්‍යතිරේකයේ අවදානම ඉවත් කළ හැකිය: " src.GetType().GetProperty(propName)?.GetValue(src, null);";).
shA.t

9
A shA.t: මම හිතන්නේ ඒක නරක අදහසක්. පවත්නා දේපලක ශුන්‍ය වටිනාකමක් හෝ කිසිසේත්ම දේපලක් නොමැති බව ඔබ වෙන් කරන්නේ කෙසේද? මම නරක දේපල නාමයකින් යවන බව මම වහාම දැනගන්නවා. මෙය නිෂ්පාදන කේතය නොවේ, නමුත් වඩා හොඳ වැඩිදියුණු කිරීමක් වනුයේ වඩාත් නිශ්චිත ව්‍යතිරේකයක් විසි කිරීමයි (උදා: ශුන්‍ය GetPropertyහා විසි කිරීම සඳහා පරීක්ෂා කිරීම PropertyNotFoundExceptionහෝ ශුන්‍ය නම් යමක්.)
එඩ් එස්.

ඔබේ දේපල සැබවින්ම ක්ෂේත්‍රයක් මිස දේපලක් නොවන්නේ නම් (මගේ වැනි;)) ඒ GetFieldවෙනුවට භාවිතා කරන්නGetProperty
ක්‍රිස්ටෝපර් කේ.

216

මේ වගේ දෙයක් ගැන:

public static Object GetPropValue(this Object obj, String name) {
    foreach (String part in name.Split('.')) {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        PropertyInfo info = type.GetProperty(part);
        if (info == null) { return null; }

        obj = info.GetValue(obj, null);
    }
    return obj;
}

public static T GetPropValue<T>(this Object obj, String name) {
    Object retval = GetPropValue(obj, name);
    if (retval == null) { return default(T); }

    // throws InvalidCastException if types are incompatible
    return (T) retval;
}

මෙය ඔබට තනි නූලක් භාවිතා කරමින් ගුණාංග වලට බැසීමට ඉඩ දෙයි,

DateTime now = DateTime.Now;
int min = GetPropValue<int>(now, "TimeOfDay.Minutes");
int hrs = now.GetPropValue<int>("TimeOfDay.Hours");

ඔබට මෙම ක්‍රම ස්ථිතික ක්‍රම හෝ දිගු ලෙස භාවිතා කළ හැකිය.


3
Red ෆ්‍රෙඩ් ජෑන්ඩ් ඔබ එයට බාධා කිරීම ගැන සතුටුයි! මෙම පැරණි තනතුරු ඉහළට එන විට එය සැමවිටම පුදුමයට කරුණකි. එය ටිකක් අපැහැදිලි නිසා මම එය පැහැදිලි කිරීම සඳහා පෙළ ටිකක් එකතු කළෙමි. මම මේවා ව්‍යාප්ති ක්‍රම ලෙස භාවිතා කිරීමට මාරුවී ඇති අතර ජනක ආකෘති පත්‍රයක් එක් කළෙමි, එබැවින් මම එය මෙහි එක් කළෙමි.
jheddings

ශුන්‍ය ආරක්ෂකයා පෙර නිමිත්තෙහි තබා ඇත්තේ ඇයි?
සැන්ටොස්

4
Ob සැන්ටොස්, පෙර නිමි පුටුවේ ශරීරය තුළ 'ඕබ්' නැවත අර්ථ දක්වා ඇති හෙයින්, එය එක් එක් පුනරාවර්තනයේදී පරීක්ෂා කරනු ලැබේ.
jheddings

ප්‍රයෝජනවත්, නමුත් කූඩුවල එක් ගුණාංගයක් සැඟවිය හැකි අද්දර ('නව' විකරණකාරකය භාවිතා කරමින්), එය අනුපිටපත් ගුණාංග සොයා ගැනීම සඳහා ව්‍යතිරේකයක් දමනු ඇත. කූඩුවල ඇති දේපලකට ප්‍රවේශ වීම සේම, අන්තිම දේපල වර්ගය පිළිබඳව PropertyInfo.PropertyTypeසොයා බැලීම obj.GetType()සහ කැදැලි දේපල වෙනුවට භාවිතා කිරීම ඉතා සුදුසුය.
නුලියස්

ඔබට nameofC # 6 ලෙස ප්‍රකාශනය භාවිතා කළ හැකිය : nameof(TimeOfDay.Minutes)මැජික් නූල් ඉවත් කිරීම සඳහා ශ්‍රිතය ඇමතීමේදී නාම පරාමිතිය මත සහ මෙම ඇමතුම් සඳහා කාල ආරක්ෂාව එකතු කරන්න.
කපාගන්න

77

ඕනෑම දෙයකට එකතු කරන්න Class:

public class Foo
{
    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }

    public string Bar { get; set; }
}

එවිට ඔබට පහත පරිදි භාවිතා කළ හැකිය:

Foo f = new Foo();
// Set
f["Bar"] = "asdf";
// Get
string s = (string)f["Bar"];

D එඩ්වාඩෝකුමෝ: මේ සමඟ පරාවර්තනය භාවිතා කළ හැකිද, එවිට පන්තියේ සාමාජිකයන් මොනවාදැයි ඔබ දැනගත යුතු නොවේද?
අපේ මිනිසා කෙසෙල්වල

"බාර්" වස්තුවක් නම් මෙය කළ හැකිද?
big_water

igbig_water SetValueසහ GetValueක්‍රම සමඟ ක්‍රියා කරයි Object. ඔබට නිශ්චිත වර්ගයක් සමඟ වැඩ කිරීමට අවශ්‍ය නම්, එහි GetValueSetValue
එඩ්වාඩෝ කියෝමෝ

කණගාටුයි ur ඕර්මානින් බනානාස්, මට ඔබේ ප්‍රශ්නය තේරුම් ගත නොහැක. ඔයාට මොනවද කරන්න ඕන?
එඩ්වාඩෝ කියෝමෝ

මෙම වර්ගයේ ක්‍රමවල නම කුමක්ද ..?
සහන්

46

මොන භාවිතා කරන ආකාරය පිළිබඳව CallByNameපිළිබඳ Microsoft.VisualBasicනාම ( Microsoft.VisualBasic.dll)? සාමාන්‍ය වස්තූන්, COM වස්තු සහ ගතික වස්තූන්ගේ ගුණාංග, ක්ෂේත්‍ර සහ ක්‍රම ලබා ගැනීමට එය පරාවර්තනය භාවිතා කරයි.

using Microsoft.VisualBasic;
using Microsoft.VisualBasic.CompilerServices;

ඊළගට

Versioned.CallByName(this, "method/function/prop name", CallType.Get).ToString();

5
සිත්ගන්නාසුලු යෝජනාව, වැඩිදුර පරීක්‍ෂණයෙන් ඔප්පු වූයේ එයට ක්ෂේත්‍ර සහ ගුණාංග, COM වස්තු යන දෙකම හැසිරවිය හැකි බවත්, එය නිවැරදිව ගතික බන්ධන හැසිරවිය හැකි බවත්ය !
ඉලිඩාන් එස් 4 ට මොනිකා නැවත අවශ්‍යයි

මට දෝෂයක් තිබේ: 'MyType' වර්ගයේ පොදු සාමාජික 'MyPropertyName' හමු නොවීය.
vldmrrdjcc

31

ජෙඩින්ග්ස් විසින් විශිෂ්ට පිළිතුරක්. සමස්ථ අරා හෝ වස්තු එකතු කිරීම සඳහා ඉඩ ලබා දෙමින් එය වැඩි දියුණු කිරීමට මම කැමැත්තෙමි, එවිට දේපල නාමය දේපල 1. ප්‍රොපර්ටි 2 [X] විය හැකිය .ප්‍රොපර්ටි 3:

    public static object GetPropertyValue(object srcobj, string propertyName)
    {
        if (srcobj == null)
            return null;

        object obj = srcobj;

        // Split property name to parts (propertyName could be hierarchical, like obj.subobj.subobj.property
        string[] propertyNameParts = propertyName.Split('.');

        foreach (string propertyNamePart in propertyNameParts)
        {
            if (obj == null)    return null;

            // propertyNamePart could contain reference to specific 
            // element (by index) inside a collection
            if (!propertyNamePart.Contains("["))
            {
                PropertyInfo pi = obj.GetType().GetProperty(propertyNamePart);
                if (pi == null) return null;
                obj = pi.GetValue(obj, null);
            }
            else
            {   // propertyNamePart is areference to specific element 
                // (by index) inside a collection
                // like AggregatedCollection[123]
                //   get collection name and element index
                int indexStart = propertyNamePart.IndexOf("[")+1;
                string collectionPropertyName = propertyNamePart.Substring(0, indexStart-1);
                int collectionElementIndex = Int32.Parse(propertyNamePart.Substring(indexStart, propertyNamePart.Length-indexStart-1));
                //   get collection object
                PropertyInfo pi = obj.GetType().GetProperty(collectionPropertyName);
                if (pi == null) return null;
                object unknownCollection = pi.GetValue(obj, null);
                //   try to process the collection as array
                if (unknownCollection.GetType().IsArray)
                {
                    object[] collectionAsArray = unknownCollection as object[];
                    obj = collectionAsArray[collectionElementIndex];
                }
                else
                {
                    //   try to process the collection as IList
                    System.Collections.IList collectionAsList = unknownCollection as System.Collections.IList;
                    if (collectionAsList != null)
                    {
                        obj = collectionAsList[collectionElementIndex];
                    }
                    else
                    {
                        // ??? Unsupported collection type
                    }
                }
            }
        }

        return obj;
    }

මාස්ටර්ලිස්ට් [0] [1] වෙත ප්‍රවේශ වූ ලැයිස්තු ලැයිස්තුවක් ගැන කුමක් කිව හැකිද?
ජෙසී ඇඩම්

Array -> වස්තුව ලෙස [] ද Nullreference ව්‍යතිරේකය ඇති කරයි. මට වැඩ කරන දෙය (මුක්කු වඩාත් කාර්යක්ෂම ක්‍රමය නොවේ), නොදන්නා එකතුව IEnumerable වෙත දැමීම සහ ප්‍රති .ලය මත ToArray () භාවිතා කිරීමට වඩා. fiddle
ජෙරොයින් ජොන්ක්මන්

15

මම එඩ් එස් වෙතින් කේතය භාවිතා කරන්නේ නම් මට ලැබෙනු ඇත

'ReflectionExtensions.GetProperty (Type, string)' එහි ආරක්ෂිත මට්ටම නිසා ප්‍රවේශ විය නොහැක

එය GetProperty()Xamarin.Forms හි නොමැති බව පෙනේ . TargetFrameworkProfileවේProfile7 මගේ අතේ ගෙන යා හැකි පන්තිය සඳහා වූ පුස්තකාලය (.NET Framework 4.5, වින්ඩෝස් 8, ASP.NET Core 1.0, Xamarin.Android, Xamarin.iOS, Xamarin.iOS සම්භාව්ය) දී.

දැන් මම වැඩ කරන විසඳුමක් සොයා ගත්තා:

using System.Linq;
using System.Reflection;

public static object GetPropValue(object source, string propertyName)
{
    var property = source.GetType().GetRuntimeProperties().FirstOrDefault(p => string.Equals(p.Name, propertyName, StringComparison.OrdinalIgnoreCase));
    return property?.GetValue(source);
}

මූලාශ්රය


4
හැකි තරම් කුඩා දියුණුවක්. IF සහ ඊළඟ ප්‍රතිලාභය ප්‍රතිස්ථාපනය කරන්න: ආපසු දේපල? .GetValue (ප්‍රභවය);
ටොමිනෝ

11

කැදැලි දේපල සාකච්ඡාව ගැන, ඔබ DataBinder.Eval Method (Object, String)පහත පරිදි භාවිතා කරන්නේ නම් සියලු පරාවර්තන දේවල් වළක්වා ගත හැකිය :

var value = DataBinder.Eval(DateTime.Now, "TimeOfDay.Hours");

ඇත්ත වශයෙන්ම, ඔබට System.Webඑකලස් කිරීම සඳහා සඳහනක් එක් කිරීමට අවශ්‍ය වනු ඇත , නමුත් මෙය විශාල ගනුදෙනුවක් නොවේ.


10

ඇමතීමේ ක්‍රමය .NET ප්‍රමිතියෙන් වෙනස් වී ඇත (1.6 වන විට). එසේම අපට C # 6 හි ශුන්‍ය කොන්දේසි සහිත ක්‍රියාකරු භාවිතා කළ හැකිය.

using System.Reflection; 
public static object GetPropValue(object src, string propName)
{
    return src.GetType().GetRuntimeProperty(propName)?.GetValue(src);
}

1
? operator
blfuentes

5

පහත ක්‍රමය මට පරිපූර්ණ ලෙස ක්‍රියා කරයි:

class MyClass {
    public string prop1 { set; get; }

    public object this[string propertyName]
    {
        get { return this.GetType().GetProperty(propertyName).GetValue(this, null); }
        set { this.GetType().GetProperty(propertyName).SetValue(this, value, null); }
    }
}

දේපල වටිනාකම ලබා ගැනීම සඳහා:

MyClass t1 = new MyClass();
...
string value = t1["prop1"].ToString();

දේපල වටිනාකම සැකසීමට:

t1["prop1"] = value;

4

System.Reflection නාම අවකාශයේ PropertyInfo භාවිතා කිරීම . අප පිවිසීමට උත්සාහ කළ දේපළ කුමක් වුවත් පරාවර්තනය සම්පාදනය කරයි. ධාවන කාලය තුළ දෝෂය පැමිණේ.

    public static object GetObjProperty(object obj, string property)
    {
        Type t = obj.GetType();
        PropertyInfo p = t.GetProperty("Location");
        Point location = (Point)p.GetValue(obj, null);
        return location;
    }

වස්තුවක ස්ථාන දේපල ලබා ගැනීම සඳහා එය හොඳින් ක්‍රියාත්මක වේ

Label1.Text = GetObjProperty(button1, "Location").ToString();

අපට ස්ථානය ලැබෙනු ඇත: {X = 71, Y = 27} අපට location.X හෝ location.Y එකම ආකාරයකින් ආපසු ලබා දිය හැකිය.


4
public static List<KeyValuePair<string, string>> GetProperties(object item) //where T : class
    {
        var result = new List<KeyValuePair<string, string>>();
        if (item != null)
        {
            var type = item.GetType();
            var properties = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
            foreach (var pi in properties)
            {
                var selfValue = type.GetProperty(pi.Name).GetValue(item, null);
                if (selfValue != null)
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, selfValue.ToString()));
                }
                else
                {
                    result.Add(new KeyValuePair<string, string>(pi.Name, null));
                }
            }
        }
        return result;
    }

මෙය සියළුම ගුණාංග ඒවායේ අගයන් සමඟ ලැයිස්තුවක් තුළ ලබා ගත හැකි ක්‍රමයකි.


මෙය කරන්නේ ඇයි: type.GetProperty(pi.Name)එය විචල්‍යයට == වන විට pi?
වෙස්ටන්

ඔබ c # 6.0 භාවිතා ifකරන්නේ selfValue?.ToString()නම්, ඉවත් කර වෙනත් ආකාරයකින් ඉවත් කර ifභාවිතා කරන්නselfValue==null?null:selfValue.ToString()
Weston

ලැයිස්තුවක් List<KeyValuePair<Dictionary<string, string>
අමුතුයි,

3

පහත දැක්වෙන කේතය වස්තුවක උදාහරණයක අඩංගු සියලුම දේපල නම් සහ වටිනාකම්වල සමස්ත ධූරාවලිය ප්‍රදර්ශනය කිරීම සඳහා පුනරාවර්තන ක්‍රමයකි. මෙම ක්‍රමය ඇලෙක්ස්ඩී හි සරල කළ අනුවාදයක් භාවිතා කරයිGetPropertyValue() ඉහත පිළිතුරේ . මෙම සාකච්ඡා නූලට ස්තූතියි, මෙය කරන්නේ කෙසේදැයි මට තේරුම් ගැනීමට හැකි විය!

නිදසුනක් ලෙස, WebServiceපහත දැක්වෙන ක්‍රමය ඇමතීමෙන් ප්‍රතිචාරයක් ලෙස සියලු දේපලවල පිපිරීමක් හෝ ඩම්ප් එකක් පෙන්වීමට මම මෙම ක්‍රමය භාවිතා කරමි :

PropertyValues_byRecursion("Response", response, false);

public static object GetPropertyValue(object srcObj, string propertyName)
{
  if (srcObj == null) 
  {
    return null; 
  }
  PropertyInfo pi = srcObj.GetType().GetProperty(propertyName.Replace("[]", ""));
  if (pi == null)
  {
    return null;
  }
  return pi.GetValue(srcObj);
}

public static void PropertyValues_byRecursion(string parentPath, object parentObj, bool showNullValues)
{
  /// Processes all of the objects contained in the parent object.
  ///   If an object has a Property Value, then the value is written to the Console
  ///   Else if the object is a container, then this method is called recursively
  ///       using the current path and current object as parameters

  // Note:  If you do not want to see null values, set showNullValues = false

  foreach (PropertyInfo pi in parentObj.GetType().GetTypeInfo().GetProperties())
  {
    // Build the current object property's namespace path.  
    // Recursion extends this to be the property's full namespace path.
    string currentPath = parentPath + "." + pi.Name;

    // Get the selected property's value as an object
    object myPropertyValue = GetPropertyValue(parentObj, pi.Name);
    if (myPropertyValue == null)
    {
      // Instance of Property does not exist
      if (showNullValues)
      {
        Console.WriteLine(currentPath + " = null");
        // Note: If you are replacing these Console.Write... methods callback methods,
        //       consider passing DBNull.Value instead of null in any method object parameters.
      }
    }
    else if (myPropertyValue.GetType().IsArray)
    {
      // myPropertyValue is an object instance of an Array of business objects.
      // Initialize an array index variable so we can show NamespacePath[idx] in the results.
      int idx = 0;
      foreach (object business in (Array)myPropertyValue)
      {
        if (business == null)
        {
          // Instance of Property does not exist
          // Not sure if this is possible in this context.
          if (showNullValues)
          {
            Console.WriteLine(currentPath  + "[" + idx.ToString() + "]" + " = null");
          }
        }
        else if (business.GetType().IsArray)
        {
          // myPropertyValue[idx] is another Array!
          // Let recursion process it.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        else if (business.GetType().IsSealed)
        {
          // Display the Full Property Path and its Value
          Console.WriteLine(currentPath + "[" + idx.ToString() + "] = " + business.ToString());
        }
        else
        {
          // Unsealed Type Properties can contain child objects.
          // Recurse into my property value object to process its properties and child objects.
          PropertyValues_byRecursion(currentPath + "[" + idx.ToString() + "]", business, showNullValues);
        }
        idx++;
      }
    }
    else if (myPropertyValue.GetType().IsSealed)
    {
      // myPropertyValue is a simple value
      Console.WriteLine(currentPath + " = " + myPropertyValue.ToString());
    }
    else
    {
      // Unsealed Type Properties can contain child objects.
      // Recurse into my property value object to process its properties and child objects.
      PropertyValues_byRecursion(currentPath, myPropertyValue, showNullValues);
    }
  }
}

3
public static TValue GetFieldValue<TValue>(this object instance, string name)
{
    var type = instance.GetType(); 
    var field = type.GetFields(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.FieldType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

public static TValue GetPropertyValue<TValue>(this object instance, string name)
{
    var type = instance.GetType();
    var field = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance).FirstOrDefault(e => typeof(TValue).IsAssignableFrom(e.PropertyType) && e.Name == name);
    return (TValue)field?.GetValue(instance);
}

3
public class YourClass
{
    //Add below line in your class
    public object this[string propertyName] => GetType().GetProperty(propertyName)?.GetValue(this, null);
    public string SampleProperty { get; set; }
}

//And you can get value of any property like this.
var value = YourClass["SampleProperty"];

2
Dim NewHandle As YourType = CType(Microsoft.VisualBasic.CallByName(ObjectThatContainsYourVariable, "YourVariableName", CallType), YourType)

2

කැදැලි මාර්ගයක් ඔබට පැවසීමට නූල් අවශ්‍ය නොවන කැදැලි දේපලක් සොයා ගැනීමට තවත් ක්‍රමයක් මෙන්න. තනි දේපල ක්‍රමය සඳහා එඩ් එස්.

    public static T FindNestedPropertyValue<T, N>(N model, string propName) {
        T retVal = default(T);
        bool found = false;

        PropertyInfo[] properties = typeof(N).GetProperties();

        foreach (PropertyInfo property in properties) {
            var currentProperty = property.GetValue(model, null);

            if (!found) {
                try {
                    retVal = GetPropValue<T>(currentProperty, propName);
                    found = true;
                } catch { }
            }
        }

        if (!found) {
            throw new Exception("Unable to find property: " + propName);
        }

        return retVal;
    }

        public static T GetPropValue<T>(object srcObject, string propName) {
        return (T)srcObject.GetType().GetProperty(propName).GetValue(srcObject, null);
    }

එය නම්, පරීක්ෂා කිරීමට වඩා හොඳ විය හැකි Type.GetPropertyප්රතිලාභ null වෙනුවට කැඳවීමේ GetValueහා සහිත NullReferenceExceptionගේ, චක්රයක් වීසි.
Groo

2

ඔබ පරීක්‍ෂා කරන්නේ කුමන වස්තුවක් දැයි ඔබ කිසි විටෙකත් සඳහන් නොකරන අතර, දී ඇති වස්තුවක් ගැන සඳහන් කරන ඒවා ඔබ ප්‍රතික්ෂේප කරන බැවින්, ඔබ අදහස් කරන්නේ ස්ථිතික එකක් යැයි මම සිතමි.

using System.Reflection;
public object GetPropValue(string prop)
{
    int splitPoint = prop.LastIndexOf('.');
    Type type = Assembly.GetEntryAssembly().GetType(prop.Substring(0, splitPoint));
    object obj = null;
    return type.GetProperty(prop.Substring(splitPoint + 1)).GetValue(obj, null);
}

දේශීය විචල්‍යය සමඟ පරීක්ෂා කරන වස්තුව මා සලකුණු කළ බව සලකන්න obj. nullස්ථිතික යන්නෙන් අදහස් කරන්නේ, එසේ නොමැතිනම් ඔබට අවශ්‍ය දේට එය සකසන්න. GetEntryAssembly()"ධාවනය" එකලස් කිරීම ලබා ගත හැකි ක්‍රම කිහිපයෙන් එකක් මෙය බව සලකන්න , ඔබට වර්ගය පැටවීමට අපහසු නම් ඔබට එය සමඟ සෙල්ලම් කිරීමට අවශ්‍ය විය හැකිය.


2

Heleonix.Reflection පුස්තකාලය දෙස බලන්න . ඔබට මාර්ගයෙන් සාමාජිකයන් ලබා ගැනීමට / සැකසීමට / ආයාචනා කිරීමට හෝ පරාවර්තනයට වඩා වේගවත් වන ගැටර් / සෙටර් (ලැම්බඩා නියෝජිතයෙකුට සම්පාදනය කර) නිර්මාණය කළ හැකිය. උදාහරණයක් වශයෙන්:

var success = Reflector.Get(DateTime.Now, null, "Date.Year", out int value);

නැතහොත් එක් වරක් ලබා ගන්නෙකු නිර්මාණය කර නැවත භාවිතා කිරීම සඳහා හැඹිලිය (මෙය වඩාත් ක්‍රියාකාරී නමුත් අතරමැදි සාමාජිකයෙකු ශුන්‍ය නම් NullReferenceException විසි කළ හැකිය):

var getter = Reflector.CreateGetter<DateTime, int>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

නැතහොත් ඔබට List<Action<object, object>>වෙනත් ලබා ගන්නන්ගෙන් කෙනෙකු සෑදීමට අවශ්‍ය නම් , සම්පාදනය කරන ලද නියෝජිතයින් සඳහා මූලික වර්ග පමණක් සඳහන් කරන්න (වර්ගය පරිවර්තනය සම්පාදනය කරන ලද ලැම්බඩා වලට එකතු කරනු ලැබේ):

var getter = Reflector.CreateGetter<object, object>("Date.Year", typeof(DateTime));
getter(DateTime.Now);

1
පේළි 5-10 කින් සාධාරණ වේලාවක ඔබේ කේතයෙන් එය ක්‍රියාත්මක කළ හැකි නම් තෙවන පාර්ශවීය ලිබ් භාවිතා නොකරන්න.
ආටෙම් ජී

1

කෙටි මාර්ගය ....

var a = new Test { Id = 1 , Name = "A" , date = DateTime.Now};
var b = new Test { Id = 1 , Name = "AXXX", date = DateTime.Now };

var compare = string.Join("",a.GetType().GetProperties().Select(x => x.GetValue(a)).ToArray())==
              string.Join("",b.GetType().GetProperties().Select(x => x.GetValue(b)).ToArray());

1

ජෙඩ්ඩිංස් සහ ඇලෙක්ස් ඩී යන දෙදෙනාම දේපල නූල් නිරාකරණය කරන්නේ කෙසේද යන්න පිළිබඳව විශිෂ්ට පිළිතුරු ලිවීය. මම ඒ සඳහා කැපවූ පුස්තකාලයක් ලියා ඇති බැවින්, මගේ මිශ්‍රණයට විසි කිරීමට මම කැමතියි.

Pather.CSharp ගේ ප්‍රධාන පන්තියResolver . පෙරනිමියෙන් එයට ගුණාංග, අරාව සහ ශබ්ද කෝෂ ඇතුළත් කිරීම් විසඳිය හැකිය.

උදාහරණයක් ලෙස, ඔබට මේ වගේ වස්තුවක් තිබේ නම්

var o = new { Property1 = new { Property2 = "value" } };

ලබා ගැනීමට අවශ්‍ය නම් Property2, ඔබට එය මේ ආකාරයෙන් කළ හැකිය:

IResolver resolver = new Resolver();
var path = "Property1.Property2";
object result = r.Resolve(o, path); 
//=> "value"

එය විසඳිය හැකි මාර්ග පිළිබඳ මූලික උදාහරණය මෙයයි. ඔබට එය කළ හැකි වෙනත් දෑ බැලීමට අවශ්‍ය නම් හෝ එය දිගු කරන්නේ කෙසේද යන්න එහි ගිතුබ් පිටුවට යන්න .


0

මෙන්න මගේ විසඳුම. එය COM වස්තු සමඟ ද ක්‍රියා කරන අතර COM වස්තු වලින් එකතු කිරීමේ / අරා අයිතම වෙත ප්‍රවේශ වීමට ඉඩ දෙයි.

public static object GetPropValue(this object obj, string name)
{
    foreach (string part in name.Split('.'))
    {
        if (obj == null) { return null; }

        Type type = obj.GetType();
        if (type.Name == "__ComObject")
        {
            if (part.Contains('['))
            {
                string partWithoundIndex = part;
                int index = ParseIndexFromPropertyName(ref partWithoundIndex);
                obj = Versioned.CallByName(obj, partWithoundIndex, CallType.Get, index);
            }
            else
            {
                obj = Versioned.CallByName(obj, part, CallType.Get);
            }
        }
        else
        {
            PropertyInfo info = type.GetProperty(part);
            if (info == null) { return null; }
            obj = info.GetValue(obj, null);
        }
    }
    return obj;
}

private static int ParseIndexFromPropertyName(ref string name)
{
    int index = -1;
    int s = name.IndexOf('[') + 1;
    int e = name.IndexOf(']');
    if (e < s)
    {
        throw new ArgumentException();
    }
    string tmp = name.Substring(s, e - s);
    index = Convert.ToInt32(tmp);
    name = name.Substring(0, s - 1);
    return index;
}

0

මෙන්න වෙනත් පිළිතුරු මත පදනම්ව මට ලැබුණු දේ. දෝෂ හැසිරවීම සමඟ නිශ්චිතව ලබා ගැනීම සඳහා ටිකක් වැඩිපුර.

public static T GetPropertyValue<T>(object sourceInstance, string targetPropertyName, bool throwExceptionIfNotExists = false)
{
    string errorMsg = null;

    try
    {
        if (sourceInstance == null || string.IsNullOrWhiteSpace(targetPropertyName))
        {
            errorMsg = $"Source object is null or property name is null or whitespace. '{targetPropertyName}'";
            Log.Warn(errorMsg);

            if (throwExceptionIfNotExists)
                throw new ArgumentException(errorMsg);
            else
                return default(T);
        }

        Type returnType = typeof(T);
        Type sourceType = sourceInstance.GetType();

        PropertyInfo propertyInfo = sourceType.GetProperty(targetPropertyName, returnType);
        if (propertyInfo == null)
        {
            errorMsg = $"Property name '{targetPropertyName}' of type '{returnType}' not found for source object of type '{sourceType}'";
            Log.Warn(errorMsg);

            if (throwExceptionIfNotExists)
                throw new ArgumentException(errorMsg);
            else
                return default(T);
        }

        return (T)propertyInfo.GetValue(sourceInstance, null);
    }
    catch(Exception ex)
    {
        errorMsg = $"Problem getting property name '{targetPropertyName}' from source instance.";
        Log.Error(errorMsg, ex);

        if (throwExceptionIfNotExists)
            throw;
    }

    return default(T);
}
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.