Как сказать C # искать свойство в базовом классе объекта? - PullRequest
1 голос
/ 10 июля 2009

Я получаю сообщение об ошибке " T не содержит определения для Id " ниже в указанной строке, хотя при отладке я вижу, что "item" действительно иметь свойство "Id" в его базовом классе .

Как указать здесь, что я хочу, чтобы C # просматривал Id в базовом классе элемента (и почему он не делает это автоматически?)?

//public abstract class Items<T> : ItemBase (causes same error)
public abstract class Items<T> where T : ItemBase
{
    public List<T> _collection = new List<T>();
    public List<T> Collection
    {
        get
        {
            return _collection;
        }
    }

    public int GetNextId()
    {
        int highestId = 0;
        foreach (T item in _collection)
        {
           //ERROR: "T does not contain a definition for Id
           if (item.Id > highestId) highestId = item.Id; 
        }

        return highestId;
    }

}

Вот как определяются классы:

public class SmartForm : Item
{
    public string IdCode { get; set; }
    public string Title { get; set; }
    public string Description { get; set; }
    public int LabelWidth { get; set; }
    public int FormWidth { get; set; }
    ...


public abstract class Item : ItemBase
{
    public int Id { get; set; }
    public DateTime WhenCreated { get; set; }
    public string ItemOwner { get; set; }
    public string PublishStatus { get; set; }
    public int CorrectionOfId { get; set; }
    ...

Ответы [ 6 ]

12 голосов
/ 10 июля 2009

Ваша проблема в том, что нет никаких ограничений на T, поэтому во время компиляции все, что знает компилятор, это то, что T является своего рода объектом. Если вы знаете, какой тип T всегда будет наследоваться, вы можете добавить общее ограничение к определению класса:

public abstract class Items<T> : ItemBase where T : Item
{
//....
}

Когда вы отлаживаете, T создается для Item (или подкласса), у которого действительно есть свойство Id, но компилятор не знает об этом во время компиляции, поэтому возникает ошибка.

4 голосов
/ 10 июля 2009

Поскольку T может быть абсолютно любым, а C # должен быть безопасным для типов. Используйте ограничение на T для типа, который имеет свойство id, и вы должны быть в порядке. См. здесь для получения дополнительной информации.

4 голосов
/ 10 июля 2009

Вы неправильно указали общее ограничение.

public abstract class Items<T> : ItemBase

должно быть:

public abstract class Items<T> where T : ItemBase

Случилось так, что, хотя у вашего класса есть коллекция предметов, ваш ItemBase не связан с T

1 голос
/ 10 июля 2009

Вы случайно позволили Предметам наследовать ItemBase, а не T наследовали ItemBase. Просто поменяй

: ItemBase

до

where T : ItemBase
1 голос
/ 10 июля 2009

Вы должны указать, что T всегда получается из ItemBase, используя предложение where.

0 голосов
/ 10 июля 2009

это может помочь: -)

   foreach (ItemBase item in _collection)
    {
       if (item.Id > highestId) highestId = (Item)item.Id; 
    }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...