Several instances of the extension method, such as extending basic types, interfaces, and using reflection to allow the extension method to use private members.

Source: Internet
Author: User

Several instances of the extension method, such as extending basic types, interfaces, and using reflection to allow the extension method to use private members.

The. net extension method can expand many types, including basic data types, interfaces, classes, and so on. If the type to be extended includes private members, how can the extension method use these private members? This article provides one-by-one experience, including:

 

■ Extend basic data types
■ Extended Interface
■ Extend the class containing private fields to obtain private fields of the Class Using Reflection
■ Extends the private nesting class of a class through reflection

 

There are several prerequisites for the extension method:
● The class of the extension method must be a static class.
● The extension method must be a static method.
● In the extension method parameter, this keyword must be added before the type Extension Parameter

 

Extend basic data types

Write an extension method for the DateTime type.

Public static class CalculateAge {public static int Age (this DateTime date, DateTime birthDate) {int birthYear = birthDate. year; int currentYear = DateTime. now. year; if (birthYear> = currentYear) {throw new Exception ("enter the correct date of birth ~~ ") ;}Else {return currentYear-birthYear-1 ;}}}

 

Client call.

Class Program {static void Main (string [] args) {try {Console. writeLine ("Enter your birth year"); DateTime d = Convert. toDateTime (Console. readLine (); DateTime dateInstance = new DateTime (); int age = dateInstance. age (d); Console. writeLine ("your current age is: {0}", age); Console. readKey ();} catch (Exception ex) {Console. writeLine (ex. message );}}}

 

Extended Interface

There is such a product model.

public class Product    {        public int Id { get; set; }        public string Name { get; set; }    }

 

Interface to obtain the product set.

public interface IProductService    {        IEnumerable<Product> GetProducts();    }

 

The interface has two implementation classes.

Public class FoodProducts: IProductService {public IEnumerable <Product> GetProducts () {return new List <Product> {new Product () {Id = 1, Name = "biscuit "}, new Product () {Id = 2, Name = "milk" };}} public class ElectronicProducts: IProductService {public IEnumerable <Product> GetProducts () {return new List <Product> {new Product () {Id = 3, Name = "fan"}, new Product () {Id = 4, name = "air conditioner "}};}}

 

Interface extension method.

public static class ProductServiceExtension    {        public static IEnumerable<Product> GetProductsById(this IProductService productService, int id)        {            return productService.GetProducts().Where(p => p.Id == id);        }    }

 

Client call.

Class Program {static void Main (string [] args) {IProductService productService = new FoodProducts (); Console. writeLine ("the total quantity under the food category is; {0}", productService. getProducts (). count (); try {Console. writeLine ("the product name found is: {0}", (productService. getProductsById (1 ). singleOrDefault ()). name);} catch (Exception ex) {Console. writeLine (ex. message);} Console. readKey ();}}


Extends the class containing private fields to obtain private fields of the Class Using Reflection.

When extending a class, we sometimes use the private fields of the class. We can get the private fields of the class through reflection.

 

There is such a class that contains private fields and public methods.

{Private DateTime _ currentTime; public void SetTime () {_ currentTime = DateTime. now;} public string GetMsg () {if (_ currentTime. hour <12) {return "Good Morning ~~ ";} Else {return" Good afternoon ~~ ";}}}

 

We hope to extend a greeting that displays English information.

Public static class DisplayMessageExtensions {public static string GetLocalMsg (this DisplayMessage message, string country) {// obtain the private field var privateField = typeof (DisplayMessage) through reflection ). getField ("_ currentTime", BindingFlags. instance | BindingFlags. nonPublic); // obtain the value of this private field var currentDateTime = (DateTime) privateField. getValue (message); if (country = "USA" & currentDateTime. hour <12) {return "Good Morning";} else {return "Good Evening ";}}}

 

Client call.

Class Program {static void Main (string [] args) {DisplayMessage displayMessage = new DisplayMessage (); displayMessage. setTime (); Console. writeLine ("Greetings from China: {0}", displayMessage. getMsg (); Console. writeLine ("How do Americans send greetings? "); Console. WriteLine (" Greetings from the United States: {0} ", displayMessage. GetLocalMsg (" USA "); Console. ReadKey ();}}

 

Extends the private nesting class of a class through reflection

When a class has a nested private class, when it is extended, sometimes the nested private class of this class is used. We can extend the private nested class through reflection.

 

There is such a ParentClass class that contains a private nested class ChildClass.

public class ParentClass    {        public string MessageFromParent()        {            return "from parent~~";        }        private class ChildClass        {            public string MessageFromChild()            {                return "from child~";            }        }    }

 

Now we need to extend this private nested class and add a method to convert it into a large write, which is completed through reflection.

Public static class NestedClassExtension {public static string ToUppeerCaseParentMessage (this ParentClass parent) {return parent. messageFromParent (). toUpper ();} public static string ToUpperCaseChildMessage (this object o) {var childUpper = ""; // obtain the private nested class var privateClass = typeof (ParentClass) in the parent class through reflection ). getNestedType ("ChildClass", BindingFlags. nonPublic); if (o. getType () = privateClass) {// obtain the nested private class method through reflection var callMethod = privateClass. getMethod ("MessageFromChild"); childUpper = (callMethod. invoke (o, null) as string ). toUpper ();} return childUpper ;}}

 

The client first obtains the type of the private nested class through reflection, and then uses the extension method of the private nested class.

Try {ParentClass p = new ParentClass (); // obtain the private nested class var privateClass = typeof (ParentClass) of the parent class through reflection ). getNestedType ("ChildClass", BindingFlags. nonPublic); // create an instance var c = Activator for the parent private nested class through reflection. createInstance (privateClass); // obtain the method of the private nested class of the parent class through reflection // var callMethod = privateClass. getMethod ("MessageFromChild"); Console. writeLine (c. toUpperCaseChildMessage ();} catch (Exception ex) {Console. writeLine (ex. message);} Console. readKey ();


How can I call the extension method through reflection?

Var mi = list. GetType (). GetMethod ("Cast ");
I first pasted his code to the console to run it. The result showed that the error could not be found. Then I thought about it, right:
Then, I rushed to MSDN to check the class in which the extension method definition is located in the Enumerable static class under the namespace of System. Linq.
Found, OK! Since this method is extended for List, is it not a normal static method for this Enumerable class? Well, in this case, I will directly reflect the static method in your static class.
List <string strings = new List <string {"1", "2", "3 "};
MethodInfo mi = typeof (Enumerable). GetMethod ("Cast", BindingFlags. Public | BindingFlags. Static );
Var list = (IEnumerable <string) mi. Invoke (null, new object [] {strings}); // an error occurred here
Oh, I used the following method to ask friends online:
Var list = (IEnumerable <string) mi.
MakeGenericMethod (typeof (string )).
Invoke (null, new object [] {strings });
This method will pass the generic method into the reflection device. Then perform reflection call.

JAVA reflection

Why do you want to set the Class name as a Class? The Class clazz mentioned later is the Class you wrote. Change the class name.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.