2012-04-18 16 views
5

để tránh nhầm lẫn tôi tóm tắt một số mã:Làm thế nào để thực hiện đa hình chung trong C#?

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main() 
     { 
      IManager<ISpecificEntity> specificManager = new SpecificEntityManager(); 
      IManager<IIdentifier> manager = (IManager<IIdentifier>) specificManager; 
      manager.DoStuffWith(new SpecificEntity()); 
     } 
    } 

    internal interface IIdentifier 
    { 
    } 

    internal interface ISpecificEntity : IIdentifier 
    { 
    } 

    internal class SpecificEntity : ISpecificEntity 
    { 
    } 

    internal interface IManager<TIdentifier> where TIdentifier : IIdentifier 
    { 
     void DoStuffWith(TIdentifier entity); 
    } 

    internal class SpecificEntityManager : IManager<ISpecificEntity> 
    { 
     public void DoStuffWith(ISpecificEntity specificEntity) 
     { 
     } 
    } 
} 

Khi tôi gỡ lỗi mã tôi nhận được một InvalidCastException trong Main().

Tôi biết rằng ISpecificEntity thực hiện IIdentifier. Nhưng rõ ràng là dàn diễn viên trực tiếp từ số IManager<ISpecificEntity> vào một IManager<IIdentifier> không hoạt động.

Tôi nghĩ rằng làm việc với hiệp phương sai có thể thực hiện thủ thuật nhưng thay đổi IManager<TIdentifier> thành IManager<in TIdentifier> cũng không giúp ích gì.

Vì vậy, có cách nào để truyền specificManager vào một IManager<IIdentifier> không?

Cảm ơn và tất cả những điều tốt đẹp nhất.

+0

vui lòng đọc: http://stackoverflow.com/questions/245607/how-is-generic-covariance-contra-variance-implemented-in-c-sharp-4-0 –

Trả lời

7

Với IManager<IIdentifier> bạn có thể làm điều như vậy:

IIdentifier entity = new NotSpecificEntity(); 
manager.DoStuffWith(entity); 

Điều đó sẽ dẫn đến ngoại lệ, trong SpecificEntityManager của bạn, bởi vì nó chỉ chấp nhận tham số kiểu ISpecificEntity

UPDATE: Bạn có thể đọc thêm về hiệp phương sai và contravariance trong C# tại Eric Lippert's blog

+0

... và đó là lý do tại sao nó không phải là không được phép làm những gì OP muốn làm. +1 –

+0

@DanielHilgarth chính xác :) –

+0

Nhưng 'ISpecificEntity' triển khai' IIdentifier'. Và 'TIdentifier' trong' IManager' chỉ chấp nhận 'IIdentifier'. Vì vậy, không nên có một ngoại lệ trong dòng đó. Liệu tôi có sai? – Palama

2

Tại sao không:

ISpecificEntity bankAccountManager = new SpecificEntity(); 
IManager<IIdentifier> manager = (IManager<IIdentifier>)bankAccountManager; 
manager.DoStuffWith(new SpecificEntity()); 

?

+0

Vì 'SpecificEntity' không phải là' IManager 'nhưng là một' IIdentifier'. – Palama

Các vấn đề liên quan