2014-11-02 64 views
0

正如我在my previous question問,我被卡住了IComparer<T>實施。IComparer <T>不能使用類作爲參數

我得到了一個接口和類,實現一個:

public interface IRoom 
{ 
    // ... 
} 

public class Room : IRoom 
{ 
    // ... 
} 

而且一個比較器親子班:

public abstract class RoomComparer : IComparer<Room> 
{ 
    public RoomComparer() 
    { 
    } 

    public abstract int Compare(Room x, Room y); 
} 

public class StandardMultipliedSquareMetersComparer : RoomComparer 
{ 
    public StandardMultipliedSquareMetersComparer() 
    { 
    } 

    public override int Compare(Room a, Room b) 
    { 
     // ... 
    } 
} 

public class SquareMetersComparer : RoomComparer 
{ 
    public SquareMetersComparer() 
    { 
    } 

    public override int Compare(Room a, Room b) 
    { 
     // ... 
    } 
} 

現在,我需要用我的IRoom兒一RoomComparer孩子一樣此類的通用類型參數:

public class Hotel<TRoom, TComparer> : IHotel, IEnumerable<TRoom> 
    where TRoom : class, IRoom 
    where TComparer : RoomComparer, new() 
{ 
    public List<TRoom> Rooms; 
    protected TComparer Comparer; 

    public Hotel(int stars, TRoom[] rooms) 
    { 
     Rooms = new List<TRoom>(); 
     _stars = stars; 
     Rooms.AddRange(rooms); 
     Comparer = new TComparer(); 
     Rooms.Sort(Comparer); 
    } 

    // ... 
} 

但編制上線

Rooms.Sort(Comparer); 

失敗,兩個錯誤

錯誤CS1502:最好的重載的方法匹配 `System.Collections.Generic.List.Sort(System.Collections.Generic.IComparer ) ' 有一些無效參數(CS1502)

錯誤CS1503:參數#1' cannot convert TComparer' 表達式來 類型`System.Collections.Generic.IComparer」(CS1503)

從我的角度來看,OOP模型是正確的,並且如果參數Hotel類的構造實現IRoom,就像這樣:new Hotel<Room, SquareMetersComparer>,比它應該被正確地傳遞到RoomsComparer類的構造函數,然後,RoomComparer應正確傳遞給List.Sort()方法。但編譯器認爲在其他方面...

所以,問題是:什麼是錯的?我們在Ubuntu 14.04上使用Mono 5.10.0

+0

這是正確的,'RoomComparer'比較'Room'類的實例,但其他比較器與'IRoom'接口工作? – takemyoxygen 2014-11-02 21:14:57

+0

@James,'StandardMultipliedSquareMetersComparer'和'SquareMetersComparer'不實現'public abstract int Compare(Room x,Room y);'所以我想這可能是一個問題,或者不是所有的代碼都被列出。 – takemyoxygen 2014-11-02 21:18:54

+0

@takemyoxygen抱歉,修正了這個問題。剛剛複製這兩個類的舊代碼版本(來自上一個問題) – shybovycha 2014-11-02 21:19:46

回答

3

TComparer定義爲繼承RoomComparer。 這意味着它執行RoomIComparer。 您的列表包含TRoom的實例,它實現了IRoom,而不是Room

1

首先,您需要修復您的SquareMetersComparerStandardMultipliedSquareMetersComparer類中的錯誤。它們覆蓋了public override int Compare(IRoom a, IRoom b),但它們應該覆蓋public override int Compare(Room a, Room b)

其次,要使用比較器和TRoom之間赤裸裸的約束,因爲這樣的:

where TRoom : class, IRoom 
where TComparer : IComparer<TRoom>, new() 

此外,協方差適用於IComparer,這意味着你還可以指定這樣的約束,如果必要的話:

where TRoom : class, IRoom 
where TComparer : IComparer<IRoom>, new() 
+0

對不起,這是這兩個類的舊代碼 - 只是從我的prev複製它們。問題 - 他們實際上實施了「比較(房間a,房間b)' – shybovycha 2014-11-02 21:21:39

相關問題