C # Lặp lại thông qua các thuộc tính Lớp


118

Tôi hiện đang đặt tất cả các giá trị của đối tượng lớp của mình Record.

Đây là mã mà tôi đang sử dụng để điền vào bản ghi tại thời điểm này, thuộc tính theo thuộc tính.

// Loop through each field in the result set
for (int i = 0; i <= resultItems.Length; i++)
{

    Record newRecord = new Record()
    {
            itemtype =   resultItems[i - (fieldCount - 0)],
            itemdesc =   resultItems[i - (fieldCount - 1)],
            prodcode =   resultItems[i - (fieldCount - 2)],
            proddesc =   resultItems[i - (fieldCount - 3)],
            curstat =    resultItems[i - (fieldCount -4)],
            totfree =    resultItems[i - (fieldCount -5)],
            totphys =    resultItems[i - (fieldCount -6)],
            pcolgroup =  resultItems[i - (fieldCount -7)],
            scolgroup =  resultItems[i - (fieldCount -8)],
            totpo =      resultItems[i - (fieldCount - 9)],
            totso =      resultItems[i - (fieldCount - 10)],
            quality =    resultItems[i - (fieldCount - 11)],
            statusdesc = resultItems[i - (fieldCount - 12)],
            groupcode =  resultItems[i - (fieldCount - 13)],
            qualitydes = resultItems[i - (fieldCount - 14)],
            pcoldesc =   resultItems[i - (fieldCount - 15)],
            scoldesc =   resultItems[i - (fieldCount - 16)],
            pgroupdesc = resultItems[i - (fieldCount - 17)],
    };
}

Tôi có thể lặp lại động qua từng thuộc tính mà không cần mã hóa cứng tất cả các tên thuộc tính không?

Một cái gì đó như vậy:

// Create new Record instance
Record newRecord = new Record();

for (int e = 0; e < propertyCount.Length - 1; e++)
{
    newRecord[fieldname] = resultItems[i - (fieldCount - e)];
}

1
Bạn đã thử Reflection chưa? stackoverflow.com/questions/997747/…
kol

1
xin hãy nhìn vào liên kết này stackoverflow.com/questions/721441/...
Enigma Nhà nước

Bạn có thể giải thích nơi và cách bạn muốn duy trì mối quan hệ giữa thuộc tính và chỉ mục trong mảng resultItems không?
Erno

Câu trả lời:


226

Bạn có thể sử dụng Reflection để làm điều này. Theo như tôi hiểu, bạn có thể liệt kê các thuộc tính của lớp mình và đặt các giá trị. Bạn sẽ phải thử điều này và đảm bảo rằng bạn hiểu thứ tự của các thuộc tính. Tham khảo Tài liệu MSDN này để biết thêm thông tin về phương pháp này.

Đối với một gợi ý, bạn có thể làm điều gì đó như:

Record record = new Record();

PropertyInfo[] properties = typeof(Record).GetProperties();
foreach (PropertyInfo property in properties)
{
    property.SetValue(record, value);
}

Ở đâu valuelà giá trị bạn đang muốn ghi trong (như vậy từ bạn resultItemsmảng).


1
Điều gì sẽ xảy ra nếu tôi muốn sử dụng property.Getvalue (someOtherClassObjectHavingExacltySameProperties) thay vì một giá trị ? (Tôi đã thử này sở hữu .SetValue (objAppointment, property.GetValue (temp));? Nhưng nó mang lại cho tôi, { "Đối tượng không phù hợp với loại mục tiêu."} )
Asif Mehmood

@MalikAsif Tôi không chắc mình hoàn toàn hiểu nhưng có vẻ như bạn đang cố tải một thuộc tính từ một loại khác. Nếu bạn đăng một câu hỏi trên SO với một ví dụ và liên kết nó ở đây, tôi sẽ xem xét cho bạn.
Samuel Slade,

1
Đây là một trình tiết kiệm cuộc sống tuyệt đối - cảm ơn bạn! Tôi đang lặp lại tất cả các thuộc tính của lớp để kiểm tra xem tôi có giá trị nào không (trước khi ghi nó sang XML)
Cordell

@Cordell, bạn đã làm điều đó như thế nào? Tôi đã thử property.GetValue () nhưng nó yêu cầu một đối tượng làm tham số.
user7792598

@ user7792598 Bạn cần chuyển đối tượng mà bạn muốn lấy giá trị thuộc tính. Nếu bạn cần thêm trợ giúp, gửi một câu hỏi StackOverflow
Samuel Slade

17
// the index of each item in fieldNames must correspond to 
// the correct index in resultItems
var fieldnames = new []{"itemtype", "etc etc "};

for (int e = 0; e < fieldNames.Length - 1; e++)
{
    newRecord
       .GetType()
       .GetProperty(fieldNames[e])
       .SetValue(newRecord, resultItems[e]);
}

1
Điều này có vẻ tốt, nhưng tôi đã hy vọng làm điều đó một cách linh hoạt, thay vì khó viết mã các tên trường trong đó. Điều này có khả thi không? Cảm ơn
Luke

Ngoài ra, có vẻ như thuộc GetPropertytính không có sẵn cho cá thể lớp của tôi. : /
Luke

không, cần phải có một ánh xạ ở đâu đó giữa các chỉ mục resultItem và tên thuộc tính.
jgauffin

1
@Coulton Làm cách nào để bạn có thể liên kết động từng thuộc tính với một chỉ mục? Đó là không thể.
Amy

bạn có thể thử nameof(Item.Field)thay vì "itemtype"để tránh cứng mã hóa như của C # 6.0
Patrick Michaelsen

2

Có, bạn có thể tạo một trình chỉ mục trên lớp Bản ghi của bạn ánh xạ từ tên thuộc tính đến thuộc tính chính xác. Điều này sẽ giữ tất cả các ràng buộc từ tên thuộc tính đến thuộc tính ở một nơi, ví dụ:

public class Record
{
    public string ItemType { get; set; }

    public string this[string propertyName]
    {
        set
        {
            switch (propertyName)
            {
                case "itemType":
                    ItemType = value;
                    break;
                    // etc
            }   
        }
    }
}

Ngoài ra, như những người khác đã đề cập, sử dụng phản xạ.


1

Tôi đã thử những gì Samuel Slade đã gợi ý. Không làm việc cho tôi. Các PropertyInfo danh sách được sắp như trống rỗng. Vì vậy, tôi đã thử những điều sau đây và nó hiệu quả với tôi.

    Type type = typeof(Record);
    FieldInfo[] properties = type.GetFields();
    foreach (FieldInfo property in properties) {
       Debug.LogError(property.Name);
    }

1
Đó sẽ là vì kiểu của bạn chỉ có các trường trên đó, không phải thuộc tính !?
jamheadart
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.