-1

我正在使用 C# 创建一个应用程序,并希望能够轻松地通过我拥有的 120 个字符串执行 foreach() 循环。所有这些字符串的构造如下:

public class _currentweekapi
    {
        public string _1_artist { get; set; }
        public string _2_artist { get; set; }
        public string _3_artist { get; set; }
        ...
    }

是否可以进行 foreach() 循环来遍历所有值。字符串是从 JSON 提要自动设置的,因此我无法将值直接放入列表中。

我已经阅读了该主题并了解通过“反射”有一些方法,但我是 C# 的新手,阅读它对我来说没有任何意义。

有人可以帮我解决这个问题,说明我该如何实现这个吗?

4

4 回答 4

2

使用反射很容易 - 试试这个

var properties = typeof(_currentweekapi).GetProperties();

foreach(PropertyInfo info in properties) {
  if (info.Name.EndsWith("artist") {
    // do something amazing
  }
}

请参阅 - http://msdn.microsoft.com/en-us/library/kyaxdd3x.aspx了解更多信息

于 2012-09-18T01:48:05.393 回答
1

您应该尝试做的第一件事是不要将字符串存储在显式命名的属性中,因为您的类定义似乎正在这样做。最合适的场景似乎是 List<string> 类型的属性,可以将它们全部保存在您的类中。这也意味着您已经准备好您的清单。
因此,如果您能够更改类或使用另一个类,它接受 JSON 提要,并在 List<string> 类型的属性上使用 .Add(),而不是显式设置 120 个属性。

像这样:

public class ArtistData
{
    public List<string> Artists{ get; set; }

    public ArtistData()
    {
        this.Artists = new List<string>(0);
    }

    public void PopulateArtists(string jsonFeed)
    {
        // here something desrializes your JSON, allowing you to extract the artists...
        // here you would be populating the Artists property by adding them to the list in a loop...
    }
}

然后,您在属性 Artists 中有您的列表,并且可以直接使用该列表,或者通过执行以下操作返回它:

string[] artists = myInstance.Artists.ToArray();

但是,您似乎已经表示您无法改变这样一个事实,即它们最终作为您向我们展示的课程中的单独属性提供给您,所以...

假设您别无选择,只能从诸如此类的类开始您展示了,这是一种可以循环遍历所有这些值的方法,正如您所要求的那样,所需要的只是将您的类实例作为每个方法都需要的一个参数传递给以下方法之一:

    // this will return a list of the values contained in the properties...
    public List<string> GetListFromProperties<T>(T instance)
    {
        Type t = typeof(T);
        PropertyInfo[] props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // As a simple list...
        List<string> artists = new List<string>(props.Length);
        for (int i = 0; i < props.Length; i++)
        {
            if(!props[i].Name.Contains("_artist")){ continue; }
            artists.Add(props[i].GetValue(instance, null).ToString());
        }

        return artists;
    }

    // this will return a dictionary which has each artist stored
    // under a key which is the name of the property the artist was in.
    public Dictionary<string,string> GetDictionaryFromProperties<T>(T instance)
    {
        Type t = typeof(T);
        PropertyInfo[] props = t.GetProperties(BindingFlags.Public | BindingFlags.Instance);

        // As a dictionary...
        Dictionary<string,string> artists = new Dictionary<string,string>(props.Length);
        for (int i = 0; i < props.Length; i++)
        {
            if(artists.ContainsKey(props[i].Name) || !props[i].Name.Contains("_artist")){ continue; }
            artists.Add(props[i].Name, props[i].GetValue(instance, null).ToString());
        }

        return artists;
    }

任何一个都应该有帮助,但不要使用字典,因为它需要更多的开销,除非你真的需要知道每个艺术家来自的属性的名称,在这种情况下,它比简单的列表更有帮助。

顺便说一句,由于这些方法是通用的,也就是说,它们接受类型为 T 的参数,相同的方法将适用于任何类实例,而不仅仅是您现在正在努力的那个。

记住:虽然目前它对您来说可能非常方便,但这不一定是解决这个问题的最佳方法。比这更好的是,我最初提出的建议是完全重新上课,所以不需要这种事情。

于 2012-09-18T02:12:29.647 回答
0

你可以这样做:

        List<string> list = new List<string>();
        foreach (var property in _currentweekapi.GetType().GetProperties())
        {
            list.Add(property.GetValue(_currentweekapi, null));               
        }
于 2012-09-18T01:46:55.843 回答
0

如果您可以确保没有其他类型的属性,那么这将起作用:

var list =
    typeof(_currentweekapi)
        .GetProperties()
        .Select(pi => (string)pi.GetValue(x, null))
        .ToList();
于 2012-09-18T01:59:05.167 回答