如何从类型列表的子类访问类

时间:2009-02-16 23:12:11

标签: c# list class

我在C#中有以下代码,我试图找出为什么我无法从类型列表的子类访问类地址的元素。这是代码

MemberList list = MemberDB.GetMembers("sql", m_page, 
    m_RecordPerPage, out count, _state);

/*******************************/

public static MemberList GetMembers(string sql, int page, 
    int pageSize, out int count, string parState)
{
    MemberList retval = new MemberList();

    SqlParameter pOut = new SqlParameter("@Count", SqlDbType.Int, 4);
    pOut.Direction = ParameterDirection.Output;

    SqlParameter[] param = new SqlParameter[]{
    new SqlParameter("@Sql", sql),
    new SqlParameter("@parState", parState),
    new SqlParameter("@Page", page),
    new SqlParameter("@PageSize", pageSize),
    pOut };

    using (SqlDataReader reader = SqlHelper.ExecuteReader(
        Helper.ConnectionString, CommandType.StoredProcedure, 
        "[app_Member_Search]", param))
    {
        while (reader.Read())
        //if (reader.Read())
        {
            retval.Add(Read(reader));
            //retval = Read(reader);
        }
    }

    count = Helper.ToInt32(pOut.Value);

    return retval;
}

<小时/>

<小时/>

public class Member
{
    private Address m_address;

    public Address Address
    {
        get { return m_address; }
        set { m_address = value; }
    }

    public Member()
    {
        m_address = new Address();
    }
}

public class MemberList : List<Member>
{
    public MemberList() { }
}

<小时/>

case "Address": 
    retval.Address.Address1 = Helper.ToString(reader[i]);
    //throw new Exception(Helper.ToString(reader[i]));
    //retval.Address1 = Helper.ToString(reader[i]);
    break;

case "Address2": 
    retval.Address.Address2 = Helper.ToString(reader[i]); 
    //retval.Address2 = Helper.ToString(reader[i]); 
    break;

case "City": 
    retval.Address.City = Helper.ToString(reader[i]);
    //retval.City = Helper.ToString(reader[i]); 
    break;

case "State": 
    retval.Address.State = Helper.ToString(reader[i]);
    //retval.State = Helper.ToString(reader[i]); 
    break;

2 个答案:

答案 0 :(得分:1)

我认为您的问题可能来自对 MemberList 类的继承层次结构的困惑。它实际上根本不是成员的子类,它是List(Of T)的子类。当你用某个类名替换 T 时,你所说的是列表应该是该类型的列表,但列表仍然是列表而不是该类型的子类。这是使用称为泛型的.net功能。您可以阅读有关泛型here的更多信息。

如果您的示例中的switch语句引用了可在您的第一个代码段中看到的相同 retval ,则需要在列表中指定一个索引才能使其工作。如:

//index should be set to the correct index for the Member you are modifying
retval[index].Address.Address1 = "Some Value";

但是,这需要您在列表中添加新成员才能生效。我可能会创建一个新的Member实例,在switch语句中设置属性,然后将其添加到最后的MemberList。这样您就可以避免每次要设置属性时都必须索引到列表中,这样就可以获得更清晰,更快速的解决方案(在执行时间和写入时间)。

答案 1 :(得分:0)

在基类上引用公共或受保护的方法或属性时,请务必在其前面添加base.

我写了一个非常抽象的例子,它应该引导你如何从子类调用父类中的函数

using System;

namespace simpletest
{
    class Program
    {
        static void Main(string[] args)
        {
            Bird sparrow = new Bird();
            Console.WriteLine("Is the bird flying? " + sparrow.IsFlying + "\n");

            Console.WriteLine("Make the bird fly.");
            sparrow.Fly();
            Console.WriteLine("Is the bird flying? " + sparrow.IsFlying + "\n");

            Console.WriteLine("Make the bird land.");
            sparrow.Land();
            Console.WriteLine("Is the bird flying? " + sparrow.IsFlying);
            Console.ReadLine();
        }
    }

    public abstract class Animal
    {
        bool _isMoving = false;

        protected bool IsMoving
        {
          get { return _isMoving; }
        }

        protected void StartMoving()
        {
            _isMoving = true;
        }

        protected void StopMoving()
        {
            _isMoving = false;
        }
    }

    public class Bird : Animal, IFlyable
    {
        public void Fly()
        {
            base.StartMoving();
        }

        public void Land()
        {
            base.StopMoving();
        }

        public bool IsFlying
        {
            get { return base.IsMoving; }
        }
    }

   interface IFlyable
   {
       void Fly();
       bool IsFlying { get; }
       void Land();
   }
}