如何从基础抽象类中访问类属性

huangapple go评论81阅读模式
英文:

How To Access Class Properties From A Base Abstract Class

问题

I'm trying to design a base abstract class that can gather all the properties from classes that are inherited from it. I'm getting the name fine, but getting the value is not working. I get the runtime error "Object does not match target". Any help is much appreciated.

public string Get()
{
    string ret = "";
    var type = GetType();
    foreach (PropertyInfo p in this.GetType().GetProperties())
    {
        ret += p.Name + "`" + p.GetValue(type) + "~";
        //i've also tried
        //ret += p.Name + "`" + p.GetValue(this) + "~";
    }

    ret = ret.TrimEnd('~');
    return ret;
}
英文:

I'm trying to design a base abstract class that can gather all the properties from classes that are inherited from it. I'm getting the name fine, but getting the value is not working. I get the runtime error "Object does not match target". Any help is much appreciated.

public string Get()
{
    string ret = "";
    var type = GetType();
    foreach (PropertyInfo p in this.GetType().GetProperties())
    {
        ret += p.Name + "`" + p.GetValue(type) + "~";
        //i've also tried
        //ret += p.Name + "`" + p.GetValue(this) + "~";
    }

    ret = ret.TrimEnd('~');
    return ret;
}

答案1

得分: 3

> 参数计数不匹配。

看起来其中一个属性是一个indexer,你可以通过检查PropertyInfo上的GetIndexParameters来忽略这样的属性(或者根据需要进行相应处理):

if (!p.GetIndexParameters().Any())
{
    ret += p.Name + "`" + p.GetValue(this) + "~";
}

@sharplab.io上演示运行时异常。

英文:

> Parameter count mismatch.

It seems that one of the properties is an indexer, you can ignore such properties by checking GetIndexParameters on the PropertyInfo (or process it accordingly if needed):

if (!p.GetIndexParameters().Any())
{
    ret += p.Name + "`" + p.GetValue(this) + "~";
}

Demo with the runtime exception @sharplab.io.

答案2

得分: 2

需要传递要获取属性值的对象

p.GetValue(this)

英文:

You need to pass the object you want to get property values from

p.GetValue(this)

答案3

得分: 1

When working with arbitrary classes, we should take into account, that we can have

  • static properties: public static int MyId => 3;
  • Indexers public int this[int index] { get => index;}
  • Write only properties public int MyId {set => m_Id = value;}

So far so good, let's query the properties:

using System.Linq;

...

public string Get() => string.Join(""~"", GetType()
  .GetProperties()
  .Where(prop => prop.CanRead)                            // readable
  .Where(prop => !prop.GetGetMethod().IsStatic)           // instance  
  .Where(prop => prop.GetIndexParameters().Length == 0)   // not an indexer
  .Select(prop => $""{prop.Name}" `{prop.GetValue(this)}""));

Another issue is string manipulations: if you have a lot of properties (long ret) adding strings can be slow. If you want to join strings, just put string.Join.

英文:

When working with arbitrary classes, we should take into account, that we can have

  • static properties: public static int MyId => 3;
  • Indexers public int this[int index] { get => index;}
  • Write only properties public int MyId {set => m_Id = value;}

So far so good, let's query the properties:

using System.Linq;

...

public string Get() => string.Join("~", GetType()
  .GetProperties()
  .Where(prop => prop.CanRead)                            // readable
  .Where(prop => !prop.GetGetMethod().IsStatic)           // instance  
  .Where(prop => prop.GetIndexParameters().Length == 0)   // not an indexer
  .Select(prop => $"{prop.Name} `{prop.GetValue(this)}"));

Another issue is string manipulations: if you have a lot of properties (long ret) adding strings can be slow. If you want to join strings, just put string.Join.

huangapple
  • 本文由 发表于 2023年6月27日 20:04:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/76564677.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定