暂时无题

还没想到

父类实现IComparable<T>接口,子类无法使用~

   这两天读了张子阳的两篇文章,基于业务对象(列表)的筛选基于业务对象(列表)的排序),如醍灌顶,大受启发。于是想在一个小网站上尝试一下。

先建立实体类,对应数据库字段,然后把数据加载到一个List<T>集合中,实现各种操作。
由于每个表都有Id这个字段,所以我写了一个抽象类;

 

public abstract class Entity
{
    
private int _id;

    
public int Id
    
{
        
get return _id; }
        
set { _id = value; }
    }

}

然后其他实体类继承这个抽象类:

 

public class User : Entity
{
    
private string _username;
    
private string _password;
    
public string UserName
    
{
        
get return _username; }
        
set { _username = value; }
    }


    

    
public string PassWord
    
{
        
get return _password; }
        
set { _password = value; }
    }


}

先来个排序吧,看一下MSDN对List<T>排序方法的说明:

 

Sort() 使用默认比较器对整个 List<T> 中的元素进行排序。
Sort(Comparison<T>) 使用指定的 System.Comparison<T> 对整个 List<T> 中的元素进行排序。
Sort(IComparer<T>) 使用指定的比较器对整个 List<T>) 中的元素进行排序。
Sort(Int32, Int32, IComparer<T>) 使用指定的比较器对 List<T> 中某个范围内的元素进行排序。

先从简单的入手,使用不带参数的那个方法,实现按Id的倒序排列。按照《基于业务对象的排序》里的说法,实体类要实现 IComparable<T> 接口,于是我在Entity上实现了。

 

public abstract class Entity : IComparable<Entity>
{
    
private int _id;

    
public int Id
    
{
        
get return _id; }
        
set { _id = value; }
    }

    
IComparable 成员
}

接下来测试一下,为了演示,就不从数据库读数据了。

 

 

public class Test
{
    
static Random rnd = new Random(Convert.ToInt32(DateTime.Now.Second));
    
public static void Main(string[] args)
    
{
        List
<User> lu = new List<User>();
        
        
for (int i = 0; i < 10; i++)
        
{
            User u 
= new User();
            u.Id 
= i;
            u.UserName 
= getUserName();
            u.PassWord 
= getPassword();
            lu.Add(u);
        }

        lu.Sort();
        lu.ForEach(
delegate(User us) { Console.WriteLine("用户Id:"+us.Id+"用户名:" + us.UserName + "密码:" + us.PassWord); });
        
        Console.Read();
    }

    
public static string getPassword()
    
{
        
string g = Guid.NewGuid().ToString();
        
return g.Substring(0, g.IndexOf('-'));
    }

    
public static string getUserName()
    
{
        
string usrchars = "1234567890";
        
int usrlen = 8;
        
string tmpstr = "";
        
int iRandNum;

        
for (int i = 0; i < usrlen; i++)
        
{
            iRandNum 
= rnd.Next(usrchars.Length);
            tmpstr 
+= usrchars[iRandNum];
        }

        
return tmpstr;
    }

}

全部代码:

 

全部代码

结果出错了。如图:

受打击了~为什么我就不行呢~

查了一下详细错误:必须至少有一个对象实现 IComparable。既然如此,那我就实现IComparable接口:

 

public abstract class Entity : IComparable
{
    
private int _id;

    
public int Id
    
{
        
get return _id; }
        
set { _id = value; }
    }


    
IComparable 成员
}

 

代码丑多了,而且不能保证传入的参数是不是Entity类型,看来比较之前应该还要做检查,我这里测试,就不写了。运行一下先,竟然正常了!!

更受打击了~为什么漂亮的代码不可以而丑陋的代码就行??

不行,IComparable接口的代码看着就不爽,一定有其他原因,再找找。又看了看张子阳的文章,发现他没有用继承。那就不要抽象类了,User直接实现IComparable<T>接口。

 

public class User :IComparable<User>
{
    
private string _username;
    
private string _password;
    
private int _id;


    
public string UserName
    
{
        
get return _username; }
        
set { _username = value; }
    }


    

    
public string PassWord
    
{
        
get return _password; }
        
set { _password = value; }
    }


    
public int Id
    
{
        
get return _id; }
        
set { _id = value; }
    }


    
public int CompareTo(User other)
    
{
        
return other.Id.CompareTo(this.Id);
    }

}

 

运行一下,结果也正常!

不明白了,难道父类实现的接口在子类身上就无效了?不应该啊。赶快恢复原来的代码试一试,还让User继承Entity,Entity实现IComparable<T>接口:

 

结果从智能提示里可以看到,User里有CompareTo方法,应该也实现了IComparable<T>接口。难道父类实现的不行,必须自己实现,试一下,不让Entity实现了:

 

public abstract class Entity
{
    
private int _id;

    
public int Id
    
{
        
get return _id; }
        
set { _id = value; }
    }

}

改由User实现:

 

public class User : Entity, IComparable<Entity>
{
    
private string _username;
    
private string _password;
    
public string UserName
    
{
        
get return _username; }
        
set { _username = value; }
    }


    

    
public string PassWord
    
{
        
get return _password; }
        
set { _password = value; }
    }



    
IComparable 成员
}

 

运行一下,结果还是出错。未能比较数组中的两个元素。(就不截图了),那把类型改为子类试试:

 

public class User : Entity, IComparable<User>
{
    
private string _username;
    
private string _password;
    
public string UserName
    
{
        
get return _username; }
        
set { _username = value; }
    }


    

    
public string PassWord
    
{
        
get return _password; }
        
set { _password = value; }
    }



    
IComparable 成员
}

 

结果正常运行~

为什么,为什么会是这样?这么搞的话我每一个实体类都要单独实现IComparable<T>接口,太麻烦了,还不如在父类里实现IComparable呢~应该有更好的方法,我是彻底晕菜了,请高手出来指点一下迷津~

 

posted on 2008-07-26 17:18  张少峰  阅读(3135)  评论(1编辑  收藏  举报

导航