1

我有一个父类,它本质上是一个美化列表。它由几个子类扩展以实现各种功能。

public class HierarchialItemList<ItemType> : IEnumerable<ItemType>
    {
        public ItemType this[String itemCode]
        {
            get
            {
                foreach (IHierarchialItem curItem in hierarchialItems)
                {
                    if (curItem.Code.Equals(itemCode, StringComparison.CurrentCultureIgnoreCase))
                    {
                        return ((ItemType)curItem);
                    }
                }
                return (default(ItemType));
            }
        }
        public ItemType this[Int32 index]
        {
            get
            {
                return (hierarchialItems[index]);
            }
        }
 }

public class DatabaseList : HierarchialItemList<Database>
{
  public DatabaseList this[CommonDatabaseType typeToFilter]
    {
        get
        {
            DatabaseList returnList = new DatabaseList();
            foreach(Database curDatabase in this)
            {
                if (curDatabase.DatabaseType.Equals(typeToFilter))
                {
                    returnList.Add(curDatabase);
                }
            }
            return (returnList);
        }
    }

    public DatabaseList this[Environments.RMSEnvironment environmentToFilter]
    {
        get
        {
            DatabaseList returnList = new DatabaseList();
            foreach(Database curDatabase in this)
            {
                if (curDatabase.ParentEnvironment.Equals(environmentToFilter))
                {
                    returnList.Add(curDatabase);
                }
            }
            return (returnList);
        }
    }


}

问题是 C# 认为:

Database testDatabase = sampleDatabaseList[0];

是一个错误,并且索引器应该返回一个 DatabaseList,而不是一个 Database。你和我都知道那是假的。任何解决方法或所有索引器都必须具有相同的返回类型吗?

编辑:我刚刚发现这是因为使用枚举作为索引器,它在内部是一个整数。不过,有什么方法可以同时使用枚举和整数?

编辑 2:根据要求,这里有一些可编译的测试代码来演示问题。

using System;
using System.Collections.Generic;

namespace CSQT
{
    class A<T>
    {
        List<T> temp;

        public A()
        {
            temp = new List<T>();
        }

        public void AddItem(T itemToAdd)
        {
            temp.Add(itemToAdd);
        }

    public T this[String code]
    {
        get { return (temp[0]); }

    }

    public T this[Int32 index]
    {
        get { return (temp[index]); }

    }
}

class B : A<String>
{
    public B()
        : base()
    {
    }

    public B this[BTypes testType]
    {
        get
        {
            return (this);
        }
    }
}

enum BTypes { TEMP1, TEMP2 };

class C
{
    public C()
    {
        B temp = new B();

        //Compile error: Cannot implicitly convert type 'CSQT.B' to 'string'
        String temp2 = temp[0];

        //Compile error: Cannot convert type 'CSQT.B' to 'string'
        String temp3 = (String)temp[0];

        //This compiles and runs but instead of going to A.this[int32], it goes to B.this[BTypes testType]
        B temp4 = temp[0];
    }
}
}
4

5 回答 5

5

为什么我们知道那是假的?线

Database testDatabase = sampleDatabaseList[0];

0使用作为文字的参数调用索引器,int因此,看到DatabaseList继承自HierarchialItemList<Database>将调用由定义的索引器

public ItemType this[Int32 itemCode] { get; }

声明返回一个ItemType. 你还没有告诉我们是什么ItemType。我们没有理由知道 anItemType可以分配给类型为 的变量Database

索引器不必返回相同的类型。但是,不可能仅根据返回类型进行重载。也就是说,这是合法的

class IndexerTest {
    public int this[int index] {
        get {
            return 0;
        }
    }

    public string this[double index] {
        get {
            return "Hello, success!";
        }
    }
}

这不是

class IndexerTest {
    public int this[int index] {
        get {
            return 0;
        }
    }

    public string this[int index] {
        get {
            return "Hello, fail!";
        }
    }
}

回应您的编辑:

编辑:我刚刚发现这是因为使用枚举作为索引器,它在内部是一个整数。不过,有什么方法可以同时使用枚举和整数?

如果要调用接受枚举的索引器,请像这样调用它:

sampleDatabaseList[Environments.RMSEnvironment.SomeEnumValue];
于 2010-01-25T21:37:27.757 回答
1

这是完全有效的代码。

class SomeClass { }
public class A<T> : IEnumerable<T>
{

    public T this[int index]
    {
        get
        {
            return (this[index]);
        }
    }

    public T this[String index]
    {
        get
        {
            return (this[index]);
        }
    }

}
public class B : A<SomeClass>
{
    public B this[char typeToFilter]
    {
        get
        {
            return new B();
        }
    }
}


        B classList = new B();
        SomeClass test = classList[0];
于 2010-01-25T21:46:49.373 回答
1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestNameSpace
{
    public class Employee : Person
    {
        string id;
        public string Id
        {
            get { return id; }
            set { id = value; }
        }

        decimal salary;
        public decimal Salary
        {
            get { return salary; }
            set { salary = value; }
        }

        string password;
        public string Password
        {
            set { password = value; }
        }

        int ichk = 1, schk = 1, pchk = 1;


        public Employee()
            : base()
        {
            Id = null;
            Salary = Convert.ToDecimal("0.0");
            Password = null;
        }

        public Employee(string n, char g, DateTime d, string empid, decimal sal, string pwd)
            : base(n, g, d)
        {
            Id = empid;
            Salary = sal;
            Password = pwd;
        }

        public override void Accept()
        {
            base.Accept();
            try
            {
                Console.Write("Enter the EMPID:");
                Id = Console.ReadLine();
                if (string.IsNullOrEmpty(Id) == true)
                {
                    ichk = 0;
                    Console.WriteLine("No ID entered!");
                }

                string salcheck;
                Console.Write("Enter the Salary:");
                salcheck = Console.ReadLine();
                if (string.IsNullOrEmpty(salcheck) == true)
                {
                    schk = 0;
                    Console.WriteLine("Invalid Salary");
                }
                else
                {
                    Salary = Convert.ToDecimal(salcheck);
                    if (Salary < 0)
                    {
                        schk = 0;
                        Console.WriteLine("Invalid Salary");
                    }
                }

                Console.Write("Enter Password:");
                Password = Console.ReadLine();
                if (string.IsNullOrEmpty(password) == true)
                {
                    pchk = 0;
                    Console.WriteLine("Empty Password!");
                }
                else
                {
                    string pwd;
                    int pchk = 0;
                    do
                    {
                        Console.Write("Re-Enter Password:");
                        pwd = Console.ReadLine();
                        if (string.IsNullOrEmpty(pwd) == true || pwd != password)
                            Console.WriteLine("Passwords don't match!");
                        else
                            pchk = 1;
                    } while (pchk == 0);
                }
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }

        }


        public override void Print()
        {
            base.Print();

            if (ichk == 1)
            {
                Console.WriteLine("EMPID:{0}", Id);
            }
            else
                Console.WriteLine("No Id!");

            if (schk == 1)
            {
                Console.WriteLine("Salary:{0}", Salary);
            }
            else
                Console.WriteLine("Invalid Salary!");

        }

    }
}

------------------------------------------------------------------

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestNameSpace
{
    public class Person
    {
        protected string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        protected char gender;
        public char Gender
        {
            get { return gender; }
            set { gender = value; }
        }

        protected DateTime? dob;
        public DateTime? Dob
        {
            get { return dob; }
            set { dob = value; }
        }

        protected int age;
        public int Age
        {
            get { return age; }
        }

        public Person()
        {
            Name = "Default";
            Gender = 'M';
            Dob = null;
            age = 0;
        }
        public Person(string n, char g, DateTime d)
        {
            Name = n;
            Gender = g;
            Dob = d;
            age = DateTime.Now.Year - Dob.Value.Year;
        }

        int nchk = 1, gchk = 0, dchk = 0;
        string datetimecheck, gendercheck;
        public virtual void Accept()
        {
            try
            {
                Console.Write("Enter the name:");
                Name = Console.ReadLine();
                if (string.IsNullOrEmpty(Name)==true)
                {
                    nchk = 0;
                    Console.WriteLine("No name entered!");
                }

                Console.Write("Enter the Date of birth:");
                datetimecheck = Console.ReadLine();
                if (string.IsNullOrEmpty(datetimecheck) == true)
                {                    
                    dchk = 0;
                    Console.WriteLine("No date entered!");
                }
                else
                {
                    Dob = Convert.ToDateTime(datetimecheck);
                    age = DateTime.Now.Year - Dob.Value.Year;
                    dchk = 1;
                }

                Console.Write("Enter Gender:");
                gendercheck = Console.ReadLine();
                if (gendercheck != "m" && gendercheck != "M" && gendercheck != "f" && gendercheck != "F")
                {
                    gchk = 0;
                    Console.WriteLine("Invalid Gender");
                }
                else
                {
                    gchk = 1;
                    Gender = Convert.ToChar(gendercheck);
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }

        }

        public virtual void Print()
        {
            Console.WriteLine("\n\nThe Employee Details are:\n");

            if (nchk == 1)
            {
                Console.WriteLine("Name:{0}", Name);
            }
            else
                Console.WriteLine("No Name!");

            if (gchk == 1)
            {
                Console.WriteLine("Gender:{0}", Gender);
            }
            else
                Console.WriteLine("No Gender!");

            if (dchk == 1)
            {
                Console.WriteLine("Date Of Birth:{0}", Dob);
                Console.WriteLine("Age:{0}", Age);
            }
            else
                Console.WriteLine("No Date Of Birth!");
        }
    }
}
于 2011-08-17T02:42:49.767 回答
0

添加必要的类和属性以编译您的代码示例后,我能够毫无问题地运行此语句:

Database testDatabase = sampleDatabaseList[0];

如果您收到sampleDatabaseList[0]返回 DatabaseList 的错误,请提供包含该语句的可编译代码示例DatabaseList testDatabase = sampleDatabaseList[0];

于 2010-01-25T21:45:06.380 回答
0
---TRIGGER--

CREATE TRIGGER TriggerTest
ON EMP
AFTER INSERT, UPDATE, DELETE 

AS
BEGIN

declare @day varchar(10)
select @day=datename(dw,getdate())

declare @hour int
Select @hour=convert(varchar(2),getdate(),114)

if ( @hour < 9 OR @hour > 13 OR @day = 'Saturday' OR @day = 'Sunday')
BEGIN

if UPDATE(EMPID)
RAISERROR ('Error!',1,16)
rollback tran

END

END

Insert into EMP values(1003,'A','A')

drop trigger TriggerTest
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestNameSpace
{
    public class Employee:Person
    {
        string id;
        public string Id
        {
            get { return id; }
            set { id = value; }
        }

        decimal salary;
        public decimal Salary
        {
            get { return salary; }
            set { salary = value; }
        }

        string password;
        public string Password
        {
            set { password = value; }
        }

        int ichk = 1, schk = 1, pchk = 1;


        public Employee()
            : base()
        {
            Id = null;
            Salary = Convert.ToDecimal("0.0");
            Password = null;
        }

        public Employee(string n, char g, DateTime d, string empid, decimal sal, string pwd)
            : base(n, g, d)
        {
            Id = empid;
            Salary = sal;
            Password = pwd;
        }

        public override void Accept()
        {
            base.Accept();
            try
            {
                Console.Write("Enter the EMPID:");
                Id = Console.ReadLine();
                if (Id == null)
                {
                    ichk = 0;
                    Console.WriteLine("No ID entered!");
                }

                Console.Write("Enter the Salary:");
                Salary = Convert.ToDecimal(Console.ReadLine());
                if (Salary < 0)
                {
                    schk = 0;
                    Console.WriteLine("Invalid Salary");
                }

                Console.Write("Enter Password:");
                Password = Convert.ToString(Console.ReadLine());
                if (password == null)
                {
                    pchk = 0;
                    Console.WriteLine("Empty Password!");
                }
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }

        }


        public override void Print()
        {
            base.Print(); 

            if (ichk == 1)
            {
                Console.WriteLine("EMPID:{0}", Id);
            }
            else
                Console.WriteLine("No Id!");

            if (schk == 1)
            {
                Console.WriteLine("Salary:{0}", Salary);
            }
            else
                Console.WriteLine("Invalid Salary!");

        }

    }
}



-----PERSON-----
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TestNameSpace
{
    public class Person
    {
        protected string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        protected char gender;
        public char Gender
        {
            get { return gender; }
            set { gender = value; }
        }

        protected DateTime dob;
        public DateTime Dob
        {
            get { return dob; }
            set { dob = value; }
        }

        protected int age;
        public int Age
        {
            get { return age; }            
        }

        public Person()
        {
            Name = "Default";
            Gender = 'M';
            Dob = Convert.ToDateTime("09 / 12 / 1990");
            age = 0;
        }
        public Person(string n, char g, DateTime d)
        {
            Name = n;
            Gender = g;
            Dob = d;
            age = DateTime.Now.Year - Dob.Year;
        }

        int nchk = 1, gchk = 1, dchk = 1;
        public virtual void Accept()
        {
            try
            {
                Console.Write("Enter the name:");
                Name = Console.ReadLine();
                if(Name == null)
                {
                    nchk = 0;
                    Console.WriteLine("No name entered!");
                }

                Console.Write("Enter the Date of birth:");
                Dob = Convert.ToDateTime(Console.ReadLine());
                if (Dob == null)
                {
                    dchk = 0;
                    Console.WriteLine("No date entered!");
                }
                else
                {
                    age = DateTime.Now.Year - Dob.Year;
                }

                Console.Write("Enter Gender:");
                Gender = Convert.ToChar(Console.ReadLine());
                if (Gender != 'm' && Gender != 'M' && Gender != 'F' && Gender != 'f')
                {
                    gchk = 0;
                    Console.WriteLine("Invalid Gender");                   
                }
            }
            catch (Exception e)
            {
                Console.Write(e.Message);
            }

        }

        public virtual void Print()
        {
            Console.WriteLine("\n\nThe Employee Details are:\n");

            if (nchk == 1)
            {
                Console.WriteLine("Name:{0}", Name);
            }
            else
                Console.WriteLine("No Name!");

            if (gchk == 1)
            {
                Console.WriteLine("Gender:{0}", Gender);
            }
            else
                Console.WriteLine("No Gender!");

            if (dchk == 1)
            {
                Console.WriteLine("Date Of Birth:{0}", Dob);
                Console.WriteLine("Age:{0}", Age);
            }
            else
                Console.WriteLine("No Date Of Birth!");
        }
    }
}
于 2011-08-16T13:27:31.827 回答