简体   繁体   中英

How to tell C# to look in an object's base class for a property?

I'm getting the error " T does not contain a definition for Id " below in the specified line, even though when I debug, I see that "item" does indeed have a property "Id" in its base class .

How do I specify here that I want C# to look in the item's base class for Id (and why doesn't it do this automatically?)?

//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;
    }

}

Here's how the classes are being defined:

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; }
    ...

Your problem is that there is no constraint on T, so, at compile time, all the compiler knows is that T is some sort of object. If you know what type T will always inherit off, you can add a generic constraint to the class definition:

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

When you're debugging, T is instantiated to an Item (or subclass of) that does have an Id property, but the compiler doesn't know that at compile time, hence the error.

You got your generic constraint wrong.

public abstract class Items<T> : ItemBase

should be:

public abstract class Items<T> where T : ItemBase

What happened is that while your class has a collection of items, your ItemBase is not associated with T

Because T could be absolutely anything, and C# is meant to be type-safe. Use a constraint on T to a type which has an id property, and you should be OK. See here for more info.

您必须使用where子句指定T始终从ItemBase派生。

You accidentally let Items inherit ItemBase, instead of T inheriting ItemBase. Just change

: ItemBase

to

where T : ItemBase

this might help :-)

   foreach (ItemBase item in _collection)
    {
       if (item.Id > highestId) highestId = (Item)item.Id; 
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM