【问题标题】:How to tell C# to look in an object's base class for a property?如何告诉 C# 在对象的基类中查找属性?
【发布时间】:2009-07-10 09:14:34
【问题描述】:

我在下面的指定行中收到错误“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; }
    ...

【问题讨论】:

  • ItemBase中Id的定义是什么?听起来像是私人的
  • ItemBase的定义是什么?

标签: c# generics inheritance


【解决方案1】:

您的问题是对 T 没有约束,因此,在编译时,编译器只知道 T 是某种对象。如果你知道什么类型 T 将永远继承,你可以在类定义中添加一个泛型约束:

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

在调试时,T 被实例化为具有 Id 属性的项(或其子类),但编译器在编译时不知道这一点,因此会出现错误。

【讨论】:

  • 我不明白...为什么 Items 继承自 ItemBase?
  • 我的应用程序中的每个项目都有一个单数和复数类,例如User --> Item --> ItemBase 和 Users --> Items --> ItemBase 其中 ItemBase 具有受保护的方法,单数和复数模型类都使用,例如 ApplicationDataPath FullXmlDataStorePathAndFileName 和 HandleXmlFileNotFound 等。
【解决方案2】:

您的通用约束错误。

public abstract class Items<T> : ItemBase

应该是:

public abstract class Items<T> where T : ItemBase

发生的情况是,虽然您的班级有一组项目,但您的 ItemBaseT 没有关联

【讨论】:

    【解决方案3】:

    因为 T 绝对可以是任何东西,而 C# 是类型安全的。对具有 id 属性的类型使用对 T 的约束,你应该没问题。请参阅here 了解更多信息。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        你不小心让 Items 继承了 ItemBase,而不是 T 继承了 ItemBase。 换个方式

        : ItemBase
        

        where T : ItemBase
        

        【讨论】:

        • 我将“public abstract class Items : ItemBase”更改为“public abstract class Items where T : ItemBase”,我得到同样的错误,更改了上面的代码。
        【解决方案6】:

        这可能会有所帮助:-)

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

        【讨论】:

        • 告诉我“从 T 型到 Itembase 的转换”是不可能的
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-09-24
        • 2021-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多