簡體   English   中英

C#.Net 3.5使用具有不同返回類型的重載索引器

[英]C# .Net 3.5 Using Overloaded Indexers with different return types

我有一個父類,從本質上講是一個榮耀的列表。 它由幾個子類擴展為各種功能。

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,而不是一個數據庫。 你和我都知道那是錯誤的。 有任何解決方法,還是所有索引器都必須具有相同的返回類型?

編輯:我剛剛發現這是因為使用枚舉作為內部為整數的索引器。 仍然可以同時使用枚舉和整數嗎?

編輯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];
    }
}
}

為什么我們知道那是假的?

Database testDatabase = sampleDatabaseList[0];

使用參數0調用索引器,該參數是一個int文字,因此,看到DatabaseList繼承自HierarchialItemList<Database>將調用以下項定義的索引器:

public ItemType this[Int32 itemCode] { get; }

聲明為返回ItemType 您尚未告訴我們什么是ItemType 我們沒有理由知道可以將ItemType分配給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];

這是完全有效的代碼。

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];
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!");
        }
    }
}

添加必要的類和屬性以使您的代碼示例得以編譯后,我能夠毫無問題地運行此語句:

Database testDatabase = sampleDatabaseList[0];

如果遇到sampleDatabaseList[0]返回DatabaseList的錯誤,請提供一個包含語句DatabaseList testDatabase = sampleDatabaseList[0];的可編譯代碼示例DatabaseList testDatabase = sampleDatabaseList[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!");
        }
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM