- Home
- Products
- Integration
- Tutorial
- Barcode FAQ
- Purchase
- Company
Note It is recommended that you use the generic Action and Func delegates that come in Visual Studio .NET
Note It is recommended that you use the generic Action and Func delegates that come QR Code JIS X 0510 Encoder In .NET Using Barcode encoder for ASP.NET Control to generate, create QR Code image in ASP.NET applications. www.OnBarcode.comGenerate Bar Code In .NET Framework Using Barcode creator for ASP.NET Control to generate, create barcode image in ASP.NET applications. www.OnBarcode.compredefined in the Framework Class Library (FCL) wherever possible . I describe these delegate types in the Enough with the Delegate Definitions Already (Generic Delegates) section of 17, Delegates . Generate QR Code ISO/IEC18004 In C# Using Barcode generator for VS .NET Control to generate, create QR Code ISO/IEC18004 image in .NET framework applications. www.OnBarcode.comCreate QR Code 2d Barcode In VS .NET Using Barcode drawer for .NET Control to generate, create Quick Response Code image in Visual Studio .NET applications. www.OnBarcode.com 12 Generics
QR-Code Creation In VB.NET Using Barcode printer for .NET Control to generate, create Denso QR Bar Code image in Visual Studio .NET applications. www.OnBarcode.comMaking Code 128C In .NET Using Barcode maker for ASP.NET Control to generate, create ANSI/AIM Code 128 image in ASP.NET applications. www.OnBarcode.comDelegate and Interface Contravariant and Covariant generic Type Arguments
Linear Creation In VS .NET Using Barcode drawer for ASP.NET Control to generate, create Linear 1D Barcode image in ASP.NET applications. www.OnBarcode.comBar Code Generation In .NET Framework Using Barcode creation for ASP.NET Control to generate, create barcode image in ASP.NET applications. www.OnBarcode.comEach of a delegate s generic type parameters can be marked as covariant or contravariant . This feature allows you to cast a variable of a generic delegate type to the same delegate type where the generic parameter types differ . A generic type parameter can be any one of the following: Print QR Code In VS .NET Using Barcode printer for ASP.NET Control to generate, create QR Code JIS X 0510 image in ASP.NET applications. www.OnBarcode.comUPC A Printer In .NET Using Barcode generation for ASP.NET Control to generate, create UPC-A image in ASP.NET applications. www.OnBarcode.comInvariant Meaning that that generic type parameter cannot be changed . I have shown only invariant generic type parameters so far in this chapter . Contravariant Meaning that the generic type parameter can change from a class to a class derived from it . In C#, you indicate contravariant generic type parameters with the in keyword . Contravariant generic type parameters can appear only in input positions such as a method s argument . Covariant Meaning that the generic type argument can change from a class to one of its base classes . In C#, you indicate covariant generic type parameters with the out keyword . Covariant generic type parameters can appear only in output positions such as a method s return type . EAN13 Generator In Visual Studio .NET Using Barcode creation for ASP.NET Control to generate, create European Article Number 13 image in ASP.NET applications. www.OnBarcode.comDelivery Point Barcode (DPBC) Drawer In .NET Framework Using Barcode generation for ASP.NET Control to generate, create Delivery Point Barcode (DPBC) image in ASP.NET applications. www.OnBarcode.comFor example, let s say that the following delegate type definition exists (which, by the way, it does): Recognizing EAN / UCC - 13 In .NET Framework Using Barcode scanner for Visual Studio .NET Control to read, scan read, scan image in VS .NET applications. www.OnBarcode.comScanning PDF417 In .NET Framework Using Barcode recognizer for Visual Studio .NET Control to read, scan read, scan image in .NET framework applications. www.OnBarcode.compublic delegate TResult Func<in T, out TResult>(T arg); Reading Universal Product Code Version A In None Using Barcode scanner for Software Control to read, scan read, scan image in Software applications. www.OnBarcode.comDraw DataMatrix In None Using Barcode generation for Office Excel Control to generate, create Data Matrix ECC200 image in Excel applications. www.OnBarcode.comHere, the generic type parameter T is marked with the in keyword, making it contravariant; and the generic type parameter TResult is marked with the out keyword, making it covariant . So now, if I have a variable declared as follows: Creating UPC Symbol In Visual Studio .NET Using Barcode creator for Reporting Service Control to generate, create UPC-A Supplement 5 image in Reporting Service applications. www.OnBarcode.comPDF-417 2d Barcode Encoder In Java Using Barcode printer for BIRT reports Control to generate, create PDF 417 image in BIRT reports applications. www.OnBarcode.comFunc<Object, ArgumentException> fn1 = null; Barcode Maker In Java Using Barcode encoder for Eclipse BIRT Control to generate, create barcode image in BIRT applications. www.OnBarcode.comGS1 128 Creation In Visual Basic .NET Using Barcode maker for Visual Studio .NET Control to generate, create UCC - 12 image in .NET applications. www.OnBarcode.comI can cast it to another Func type, where the generic type parameters are different: Func<String, Exception>fn2 = fn1;// No explicit cast is required here Exception e = fn2(""); What this is saying is that fn1 refers to a function that accepts an Object and returns an ArgumentException . The fn2 variable wants to refer to a method that takes a String and returns an Exception . Since you can pass a String to a method that wants an Object (because String is derived from Object), and since you can take the result of a method that returns an ArgumentException and treat it as an Exception (because Exception is a base class of ArgumentException), the code above compiles and is known at compile time to preserve type safety . Part II Designing Types
Note Variance applies only if the compiler can verify that a reference conversion exists between
types . In other words, variance is not possible for value types because boxing would be required . In my opinion, this restriction is what makes these variance features not that useful . For example, if I have the following method: voidProcessCollection(IEnumerable<Object> collection) { ... } I can t call it passing in a reference to a List<DateTime> object since a reference conversion doesn t exist between the DateTime value type and Object even though DateTime is derived from Object . You solve this problem by declaring ProcessCollection as follows: void ProcessCollection<T>(IEnumerable<T> collection) { ... } Plus, the big benefit of ProcessCollection(IEnumerable<Object> collection) is that there is only one version of the JITted code . However, with ProcessCollection<T>(IEnumerable<T> collection), there is also only one version of the JITted code shared by all Ts that are reference types . You do get other versions of JITted code for Ts that are value types, but now you can at least call the method passing it a collection of value types . Also, variance is not allowed on a generic type parameter if an argument of that type is passed to a method using the out or ref keyword . For example, the line of code below causes the compiler to generate the following error message: "Invalid variance: The type parameter 'T' must be invariantly valid on 'SomeDelegate<T>.Invoke(ref T)'. 'T' is contravariant." delegate void SomeDelegate<in T>(ref T t); When using delegates that take generic arguments and return values, it is recommended to always specify the in and out keywords for contravariance and covariance whenever possible, as doing this has no ill effects and enables your delegate to be used in more scenarios . Like delegates, an interface with generic type parameters can have its type parameters be contravariant or covariant . Here is an example of an interface with a contravariant generic type parameter: public interface IEnumerator<out T> : IEnumerator { Boolean MoveNext(); T Current { get; } } Since T is contravariant, it is possible to have the following code compile and run successfully: // This method accepts an IEnumerable of any reference type Int32 Count(IEnumerable<Object> collection) { ... } ... // The call below passes an IEnumerable<String> to Count Int32 c = Count(new[] { "Grant" });
|
|