Trong đoạn mã sau tôi mong đợi có thể truyền hoàn toàn từ elements
đến baseElements
vì TBase
được chuyển đổi hoàn toàn thành IBase
.Đây có phải là lỗi hiệp phương sai trong C# 4 không?
public interface IBase { }
public interface IDerived : IBase { }
public class VarianceBug
{
public void Foo<TBase>() where TBase : IBase
{
IEnumerable<TBase> elements = null;
IEnumerable<IDerived> derivedElements = null;
IEnumerable<IBase> baseElements;
// works fine
baseElements = derivedElements;
// error CS0266: Cannot implicitly convert type
// 'System.Collections.Generic.IEnumerable<TBase>' to
// 'System.Collections.Generic.IEnumerable<IBase>'.
// An explicit conversion exists (are you missing a cast?)
baseElements = elements;
}
}
Tuy nhiên, tôi nhận được lỗi được đề cập trong nhận xét.
Trích dẫn từ spec:
Một loại
T<A1, …, An>
là sai-mui trần cho một loạiT<B1, …, Bn>
nếuT
hoặc là một giao diện hoặc một loại đại biểu tuyên bố với các thông số loại biến thểT<X1, …, Xn>
, và đối với mỗi tham số kiểu biến thểXi
một trong những điều sau đây giữ:
Xi
là hiệp biến và một tham chiếu ngầm hoặc chuyển đổi danh tính tồn tại từAi
đểBi
Xi
là contravariant và một tham chiếu ngầm hoặc chuyển đổi danh tính tồn tại từBi
đểAi
Xi
là bất biến và chuyển đổi danh tính tồn tại từAi
đểBi
Kiểm tra mã của tôi, nó có vẻ phù hợp với thông số:
IEnumerable<out T>
là một kiểu giao diệnIEnumerable<out T>
được khai báo với các thông số loại biến thểT
là hiệp biếnmột chuyển đổi tài liệu tham khảo ngầm tồn tại
TBase
-IBase
Vậy - có phải là lỗi trong trình biên dịch C# 4 không?
gì xảy ra khi bạn cast một cách rõ ràng? Trình biên dịch nói rằng có một. Vì bạn đang downcasting nó kinda làm cho tinh thần ..? – flq
Chỉ để làm cho nó rõ ràng - nó là viên đạn cuối cùng của bạn "một chuyển đổi tham chiếu ngầm định tồn tại từ TBase sang IBase" là không đúng sự thật (trừ khi bạn thêm ': class'). Nó có thể được gán, nhưng nó là * không * nhất thiết là một chuyển đổi tham chiếu. Không có ': class', nó là một chuyển đổi" hạn chế ", là một phép thuật cho phép các phương thức gọi IL giống nhau (bao gồm cả các trình truy cập thuộc tính) trên các kiểu tham chiếu và kiểu giá trị theo cùng một cách: http://msdn.microsoft .com/vi-us/library/system.reflection.emit.opcodes.constrained.aspx –
Charles: bạn sai - công việc chuyển nhượng đầu tiên (Hoạt động trên Máy của tôi (TM)). –