Câu hỏi này là khá khó hiểu . Hãy để tôi xem nếu tôi có thể làm rõ nó.
Khi tôi cố gắng thực hiện IGreatInterface
cờ biên dịch một lỗi cho aMethodBeta()
vì tôi đã thực hiện rằng phương pháp sử dụng một subtype của IAnInterface
Tôi muốn thực hiện phương pháp như thế này: Object aMethodBeta(AnInterestingClass parameter)
.
Điều đó không hợp pháp. Đơn giản hóa một phần:
class Food {}
class Fruit : Food {}
class Meat : Food {}
interface IEater
{
void Eat(Food food);
}
class Vegetarian : IEater
{
public void Eat(Fruit fruit);
}
Lớp Vegetarian
không hoàn thành hợp đồng IEater
. Bạn sẽ có thể vượt qua bất kỳ Thực phẩm nào để ăn, nhưng chỉ Vegetarian
mới chấp nhận trái cây. C# không hỗ trợ phương sai tham số chính thức của phương thức ảo vì đó không phải là an toàn.
Bây giờ, sau đó bạn có thể nói, như thế nào về vấn đề này:
interface IFruitEater
{
void Eat(Fruit fruit);
}
class Omnivore : IFruitEater
{
public void Eat(Food food);
}
Bây giờ chúng tôi đã có loại an toàn; Omnivore
có thể được sử dụng như một IFruitEater
vì một Omnivore
có thể ăn trái cây, cũng như bất kỳ thực phẩm nào khác.
Thật không may, C# không hỗ trợ phương pháp ảo loại tham số chính thức contravariance mặc dù làm như vậy là trong các loại an toàn lý thuyết. Rất ít ngôn ngữ hỗ trợ điều này.
Tương tự, C# không hỗ trợ phương thức trả về phương thức ảo.
Tôi không chắc liệu điều đó có thực sự trả lời câu hỏi của bạn hay không. Bạn có thể làm rõ câu hỏi?
UPDATE:
gì về:
interface IEater
{
void Eat<T>(T t) where T : Food;
}
class Vegetarian : IEater
{
// I only want to eat fruit!
public void Eat<Fruit>(Fruit food) { }
}
Không, đó không phải là quy phạm pháp luật trong hai. Hợp đồng của IEater
là bạn sẽ cung cấp phương thức Eat<T>
có thể mất bất kỳ T
nào là Food
.Bạn có thể không phần thực hiện hợp đồng, bất kỳ hơn bạn có thể làm điều này:
interface IAdder
{
int Add(int x, int y);
}
class Adder : IAdder
{
// I only know how to add two!
public int Add(2, int y){ ... }
}
Tuy nhiên, bạn có thể làm điều này:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Vegetarian : IEater<Fruit>
{
public void Eat(Fruit fruit) { }
}
Đó là hoàn toàn hợp pháp. Tuy nhiên, bạn không thể làm:
interface IEater<T> where T : Food
{
void Eat(T t);
}
class Omnivore : IEater<Fruit>
{
public void Eat(Food food) { }
}
Bởi vì một lần nữa, C# không hỗ trợ phương thức ảo sai lệch hoặc hiệp phương sai.
Lưu ý rằng C# không hỗ trợ đa hình tham số hiệp phương sai khi làm như vậy được biết là an toàn. Ví dụ: điều này là hợp pháp:
IEnumerable<Fruit> fruit = whatever;
IEnumerable<Food> food = fruit;
Một chuỗi trái cây có thể được sử dụng như một chuỗi thức ăn. Hoặc,
IEnumerable<Fruit> fruitComparer = whatever;
IComparable<Apples> appleComparer = fruitComparer;
Nếu bạn có thứ gì đó có thể so sánh hai quả thì có thể so sánh hai quả táo bất kỳ.
Tuy nhiên, loại hiệp phương sai và đối nghịch này chỉ là hợp pháp khi tất cả những điều sau là đúng: (1) phương sai được chứng minh là an toàn, (2) tác giả của loại thêm chú thích phương sai cho thấy đồng và contra mong muốn -ngân số, (3) các kiểu đối số khác nhau có liên quan là tất cả các kiểu tham chiếu, (4) kiểu generic là một delegate hoặc một giao diện.
Tôi không hiểu câu hỏi của bạn. Bạn có thể đăng mã thực hiện IGreatInterface và lỗi trình biên dịch cụ thể không? – phoog
@Juan: Cũng giống như một lưu ý phụ giúp đánh dấu nội dung cập nhật của bạn bằng * cập nhật * hoặc thứ gì đó để chúng tôi thấy những gì đã thay đổi. –