-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フィードを受け入れ、120個のプロパティを明示的に設定するのではなく、List <string>型のプロパティで.Add()を使用する別のクラスを使用します。

このような:

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();

しかし、あなたは、あなたが私たちに見せたクラスの個々のプロパティとしてそれらがあなたに提供されるという事実を変えることはできないと言ったようです、それで...

あなたが選択の余地がないと仮定して、そのようなクラスから始めるあなたが示したように、これはあなたが要求したように、これらすべての値をループする方法です。必要なのは、クラスインスタンスをそれぞれが必要とする1つのパラメータとして以下のメソッドの1つに渡すことだけです。

    // 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 に答える