C# 列出自定义类成员和类型

C# 列出自定义类成员和类型,c#,C#,这似乎是有史以来最基本的事情,但不知怎的,我找不到答案,也弄不明白 假设我有一个自定义类: public class WineCellar { public string year; public string wine; public double nrbottles; } 现在我想要一个函数: WineCellar ex = new WineCellar(); ex.members(); 这应该会回来:年份,葡萄酒,靴子 以及: 应该返回:string,string,d

这似乎是有史以来最基本的事情,但不知怎的,我找不到答案,也弄不明白

假设我有一个自定义类:

public class WineCellar
{
   public string year;
   public string wine;
   public double nrbottles;
}
现在我想要一个函数:

WineCellar ex = new WineCellar();
ex.members();
这应该会回来:年份,葡萄酒,靴子

以及:

应该返回:string,string,double

我猜同样的,假设你有一个例子{2010,Rioja,6}。是否有通过索引返回这些的语法?i、 e

ex[1] 

回到2010年

很抱歉提出这个基本问题。

您可以使用反射

foreach (var prop in typeof(WineCellar).GetProperties())
            {

                if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?))
                {

                }
            }
要获取该值,可以执行以下操作:

prop.GetValue(obj);
你可以使用反射

foreach (var prop in typeof(WineCellar).GetProperties())
            {

                if (prop.PropertyType == typeof(double) || prop.PropertyType == typeof(double?))
                {

                }
            }
要获取该值,可以执行以下操作:

prop.GetValue(obj);

这就是实现Members方法的方法(如果您希望属性名为字符串)

但要使这些方法起作用,您应该将变量更改为如下属性

public string this[int n]
{
   get
   {
       int current = 0;
       foreach (var prop in typeof(WineCellar).GetProperties())
       {
          if (current == n)
             return prop.GetValue(this, null).ToString();
          current++;
       }
       return null;
   }
}
public class WineCellar
{
   public string Year { get; set; }
   public string Wine { get; set; }
   public double Nrbottles { get; set; }
}

这就是实现Members方法的方法(如果您希望属性名为字符串)

但要使这些方法起作用,您应该将变量更改为如下属性

public string this[int n]
{
   get
   {
       int current = 0;
       foreach (var prop in typeof(WineCellar).GetProperties())
       {
          if (current == n)
             return prop.GetValue(this, null).ToString();
          current++;
       }
       return null;
   }
}
public class WineCellar
{
   public string Year { get; set; }
   public string Wine { get; set; }
   public double Nrbottles { get; set; }
}

正如米歇尔在评论中所说,这听起来像是对一个更大问题的错误做法

但是,如果您确实需要这种东西,您可以使用反射:

//returns a list of propertyInfo objects for the class 
// with all kinds of usefull information
public List<PropertyInfo> GetMemberInfos()
{
    return this.GetType().GetProperties().ToList();
}

//returns a list of property names
public List<string> GetMemberNames
{
    return this.GetType().GetProperties().Select(pi => pi.Name).ToList();
}

//returns a list of names of the property types
public List<string> GetMemberTypeNames
{
    return this.GetType().GetProperties().Select(pi => pi.PropertyType.Name).ToList();
}

//indexer that uses the property name to get the value
//since you are mixing types, you can't get more specific than object
public object this[string property]
{
  get { return this.GetType().GetProperty(property).GetValue(this); }
  set { this.GetType().GetProperty(property).SetValue(this, value); }
}

//indexer that uses the property index in the properties array to get the value
public object this[int index]
{
  get { return this.GetType().GetProperties()[index].GetValue(this); }
  set { this.GetType().GetProperties()[index].SetValue(this, value); }
}

你曾经习惯于使用
酒窖[1]=“黑比诺”
,现在很可能会更新
地区的
属性,而不是
葡萄酒的
属性。

正如米歇尔在评论中所说,这听起来像是解决更大问题的错误方法

但是,如果您确实需要这种东西,您可以使用反射:

//returns a list of propertyInfo objects for the class 
// with all kinds of usefull information
public List<PropertyInfo> GetMemberInfos()
{
    return this.GetType().GetProperties().ToList();
}

//returns a list of property names
public List<string> GetMemberNames
{
    return this.GetType().GetProperties().Select(pi => pi.Name).ToList();
}

//returns a list of names of the property types
public List<string> GetMemberTypeNames
{
    return this.GetType().GetProperties().Select(pi => pi.PropertyType.Name).ToList();
}

//indexer that uses the property name to get the value
//since you are mixing types, you can't get more specific than object
public object this[string property]
{
  get { return this.GetType().GetProperty(property).GetValue(this); }
  set { this.GetType().GetProperty(property).SetValue(this, value); }
}

//indexer that uses the property index in the properties array to get the value
public object this[int index]
{
  get { return this.GetType().GetProperties()[index].GetValue(this); }
  set { this.GetType().GetProperties()[index].SetValue(this, value); }
}

您已经习惯于使用
winecillar[1]=“黑比诺”
,它现在很可能会更新
region
属性,而不是
wine
属性。

好吧,如果我使用ex.gettype()它会返回winecillar,但这不是我想要的。似乎没有其他东西符合兴趣点,数组是零索引的,因此
ex[1]
将返回
wine
的值,而不是
year
。关于实际问题,你有什么特别的原因想这样做吗?如果你想用它来解决一个更大的问题,几乎肯定有一个更简单更好的方法。同意@Michelle。看得很公平。更重要的是,如果需要添加新功能,我只想在一个地方调整代码。目前,我必须在类中执行此操作,然后在使用OleDB插入DB时再次执行此操作,因为我不知道如何为表的列名编制索引。我想要的是在Access中创建表并粘贴列表的镜像。这有意义吗?@nik那么你应该问这个问题。打开一个新问题,写一个完整的问题,询问如何做到这一点。好吧,如果我使用ex.gettype()它会返回winecellar,但这不是我想要的。似乎没有其他东西符合兴趣点,数组是零索引的,因此
ex[1]
将返回
wine
的值,而不是
year
。关于实际问题,你有什么特别的原因想这样做吗?如果你想用它来解决一个更大的问题,几乎肯定有一个更简单更好的方法。同意@Michelle。看得很公平。更重要的是,如果需要添加新功能,我只想在一个地方调整代码。目前,我必须在类中执行此操作,然后在使用OleDB插入DB时再次执行此操作,因为我不知道如何为表的列名编制索引。我想要的是在Access中创建表并粘贴列表的镜像。这有意义吗?@nik那么你应该问这个问题。打开一个新问题,写一个完整的问题,询问如何做到这一点。+1小注释,在这种情况下,应该是
GetFields
,而不是
GetProperties
。(尽管这再一次说明了OP想要的方法是多么脆弱)。@DaxFohl我完全没有意识到这些实际上是公共领域(哦,恐怖)。谢谢你的回答。我现在明白了。这是一个非常糟糕的方法。也许最好让它不动。更大的问题贴在这里:-如果你有建议,这将是非常欢迎+1小提示,在这种情况下,它应该是
GetFields
,而不是
GetProperties
。(尽管这再一次说明了OP想要的方法是多么脆弱)。@DaxFohl我完全没有意识到这些实际上是公共领域(哦,恐怖)。谢谢你的回答。我现在明白了。这是一个非常糟糕的方法。也许最好让它不动。更大的问题贴在这里:-如果你有建议,这将是非常欢迎!