tôi nghi ngờ câu trả lời là không, nhưng tôi muốn biết nếu nó có thể làm điều gì đó như thế này:Có thể hạn chế một tham số kiểu phương thức chung của C# như "có thể gán từ" tham số kiểu của lớp có chứa không?
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TSomeInterface>()
// This doesn't compile.
where TSomeClass : TSomeInterface
{
//...
}
}
Những gì tôi có nghĩa là để chỉ ra ở trên ví dụ (không làm việc) là để hạn chế TSomeInterface
như vậy rằng nó có thể là bất kỳ lớp cơ sở, giao diện thực hiện, hoặc (nếu bạn thực sự muốn có được chuyển đổi tiềm ẩn) tiềm ẩn của MyGenericClass
.
LƯU Ý: tôi nghi ngờ rằng lý do tại sao điều này không bao giờ được thực hiện trong C# là trở ngại chung là không thực sự có nghĩa là hợp đồng mã, mà là cách tôi đang cố gắng sử dụng chúng ở đây. Tôi thực sự không quan tâm loại TSomeInterface
là gì, miễn là nó được triển khai bởi TSomeClass
.
Cho đến nay, tôi đã bị hack này với nhau:
public class MyGenericClass<TSomeClass> {
public void MyGenericMethod<TIntermediateType, TSomeInterface>()
where TIntermediateType : TSomeClass, TSomeInterface
{
//...
}
}
này nhiều hay ít thực thi các hạn chế mà tôi muốn (mà TSomeClass
phải kế thừa từ, hoặc trong trường hợp của một giao diện, thực hiện, TSomeInterface
), nhưng gọi nó là rất vụng về, vì tôi phải chỉ rõ TIntermediateType
(mặc dù tôi thực sự muốn nó để đánh giá đối với TSomeClass
):
var myGenericInstance = new MyGenericClass<TSomeClass>();
myGenericInstance.MyGenericMethod(TSomeClass, TSomeInterface);
Bên cạnh đó, các xe cho thuê ở trên bị phá vỡ vì một người gọi có thể trong ory chỉ định một lớp con của TSomeClass
làm thông số loại đầu tiên, nơi chỉ có lớp con triển khai TSomeInterface
.
Lý do mà tôi muốn làm này là tôi đang viết một mô hình nhà máy thông thạo cho một dịch vụ WCF, và tôi sẽ như để ngăn chặn người gọi (tại thời gian biên dịch) từ cố gắng để tạo ra một thiết bị đầu cuối với một hợp đồng mà lớp dịch vụ không thực hiện. Tôi rõ ràng có thể kiểm tra này lúc chạy (WCF trong thực tế hiện điều này cho tôi), nhưng tôi là một fan hâm mộ lớn của kiểm tra thời gian biên dịch.
Có cách nào tốt hơn/thanh lịch hơn để đạt được những gì tôi ở đây không?
Điều này thực tế là không thể vì bạn đang cố gắng kết hợp các generics với thời gian chạy. – Polity
Không, tôi không có. Tôi chỉ cố gắng áp dụng một ràng buộc chung (theo như tôi có thể nói) ngôn ngữ C# không cho phép (ràng buộc một tham số kiểu sao cho nó là một siêu lớp hoặc giao diện thực hiện của một tham số kiểu trong lớp chứa). –
Theo tôi thấy, bạn cố gắng hạn chế lớp chung dựa trên loại dữ liệu bạn nạp vào một phương thức.Nếu bạn muốn hạn chế lớp chung của mình, bạn cần phải làm điều này ở cấp độ lớp (logic), không có cách nào để trình biên dịch JIT tạo ra một lớp cụ thể. – Polity