Can C # generic type parameters be constrained by constructors with parameters ?,

Source: Internet
Author: User

Can C # generic type parameters be constrained by constructors with parameters ?,

After the Review, I am very ashamed to see the title. My language skills are too poor. I guess... sorry ...... I wrote this sentence back to the beginning ......

 

 

Problem

I encountered a problem the day before yesterday, so I sent a question on MSDN. I just enriched my questions about generics.

It is often a strange idea to try DDD with EF recently, for example, "Can EF Model First add generic support ". This is "Can a generic type have a parameter constraint ".

The idea is simple. When I use generics, I find that I need to instantiate a type parameter:

1 class MyClass<T>2 {3     public MyClass1()4     {5         this.MyObject = new T();6     }7 8     T MyObject { get; set; }9 }

Of course,The preceding error is reported..

The error message is that T does not have a new constraint. Check MSDN and obtain the new constraint of the generic type parameter.

So the correct code is:

 1 class MyClass<T> 2     where T : new() 3 { 4     public MyClass1() 5     { 6         this.MyObject = new T(); 7     } 8  9     T MyObject { get; set; }10 }

 

Then, I found that I needed to create a new object based on the parameters, and this method is most suitable for implementation in generic constructors, so I hope to have such code:

 1 class MyClass1<T> 2     where T : new(string) 3 { 4     public MyClass(string request) 5     { 6         this.MyObject = new T(request); 7     } 8  9     T MyObject { get; set; }10 }

It is a pity that the error is too big. Then, check the list of generic constraints and findThere is no constructor with parameters..

 

So I encountered the question I asked on MSDN and sought an "elegant solution ".

 

Generally, there are two solutions like the answers in the question. They are also the two that I have tried but are uncomfortable with. Let's take a look at them one by one.

Supplement:

  • Reminded by James. Ying, and passed in from the constructor
  • Remind @ Choo to use Activator. CreateInstance

 

 

Factory Model

The first is Factory Pattern, which is to build a Factory class. First, let's look at the code. This is one of the writing methods. Please do not tangle on Factory Pattern:

 1 class MyClass<T, TFactory> 2     where TFactory : IFactory<T>, new() 3 { 4     public MyClass(string request) 5     { 6         var factory = new TFactory(); 7  8         this.MyObject = factory.New(request); 9     }10 11     T MyObject { get; set; }12 }13 14 interface IFactory<T>15 {16     T New(string request);17 }

You will find that,In this way, you need to create and maintain a Factory class for each derived class or instance category, so that the generic type itself is not that significant. It was originally used to reduce the type reuse Logic.

 

 

Static abstract methods of abstract base classes

If you do not want to maintain one more class, you can start with the target class, so we can create a base class for the target class:

 1 class MyClass<T> 2     where T : TBase, new() 3 { 4     public MyClass(string request) 5     { 6         this.MyObject = T.New(request); 7     } 8  9     T MyObject { get; set; }10 }11 12 abstract class TBase13 {14     public abstract static TBase New(string request);15 }

To prevent false positives, first of all,This will cause compilation errors!

The constraint is correct, but the error is similar to "T is a type parameter and cannot be used like this !" ('T'is a' type parameter ', which is not valid in the given context ).

 

 

Input from the constructor

Another basic practice is missing. James. Ying reminds me that it is passed in from the constructor of the generic class.

class MyClass<T>    where T : TBase, new(){    public MyClass(T myObject)    {        this.MyObject = myObject;    }    T MyObject { get; set; }}

This method makes the generic class much simpler, and the instantiation process is handed over to the caller, A bit of dependency is put upside down (in fact, All implementations that should be implemented in generics are handed over to callers or successors ).

The advantage is that generics are simple, but you cannot guarantee that the constructor used for instantiation is T (string ). In addition, it may reduce code reusability. If the instantiation is conditional and the logic of all derived classes is unified, it is better to implement it in the generic base class.

In simple cases, this is the most elegant method for generics.

 

 

Activator. CreateInstance

This method can be seen in http://msdn.microsoft.com/en-us/library/system.activator.createinstance (v = vs.110). aspx, the description is more clear:

Use the most matched constructor to create an instance (Creates an instance of the specified type using the constructor that best matches the specified parameters ).

Writing is also refreshing:

class MyClass<T>{    public MyClass(string request)    {        this.MyObject = (T)Activator.CreateInstance(typeof(T), request);    }    T MyObject { get; set; }}

This method is also very short, and there is no need to do more interfaces and base classes.

The disadvantage is that there is no constraint, and there is no way to ensure that T can have constructor with specified quantity and type parameters, or whether there is a constructor.

If T does not meet the design requirements, an exception is reported.

 

 

This is the original design of generic type parameters.

Now, we can know that in the generic Type of C #, the Type parameter is a kind of "non-class" existence, and the Type parameter Constraints (Constraints on Type Parameters) it is only used to describe the conditions that a specific class must meet during instantiation or inheritance. In generics, the type parameter is only a "special existence", which is used to describe the class, but cannot be used as a class.

 

 

The type parameters can be ......

First, the problem is whether generic type parameters can be instantiated with parameters, such as T myObject = new T ("Hello World! ").

Then, because the type parameters use the "constraint" method to describe the characteristics of the Instance class, the problem becomes whether generic type parameters can be constrained by constructors with parameters, such as where T: new (string ).

To make a hypothesis, it starts with a false positive. It is necessary to prove whether it has any principle problems.

First, we can compare the constraints of generic type parameters with constructors without parameters, what if a generic type parameter has a constructor with parameters? At least, the constraints of the constructor without parameters for the generic type parameters prove that the constructor's constraints for the generic type parameters do not cause any problems and technically they can be used.. (......)

We usually use two initialization methods when instantiating a new object:

  • Passing Parameters Using Constructors
  • Assign value after instantiation

In most cases, the results produced by the two methods are similar. In most cases, the properties or parameters involved are both public and open-read-write, therefore, both internal and external writes are similar.

However, in some cases, such as some business constraints, the parameters must be processed or operated using the parameters. The final operation result is private ), therefore, it is preferred to use constructors to transmit parameters. Or a special method will be used to bring the required data into the class after the class is instantiated, which is slightly less refreshing in one breath.

Using constructors to pass parameters is not an easy alternative, because it is the best solution in most of its scenarios.. Sometimes it is best to initialize an object for use in one breath, because the transaction itself has a strong atomicity. The two initialization methods of an object cause the trouble of Dual-entry. as a user of this class, sometimes you will blur the results produced by the two methods. For developers, the two implementation methods also require either the two or the two must be consistent. When the class becomes relatively complex, it is not that simple.

Therefore, we do need some scenarios where generic type parameters are constrained by constructor with parameters. Although not necessary, it is definitely a need, just like the get/set accesser.

 

 

In addition, the larger proposition is whether type parameters can be used as classes.

If it can be constrained by constructors with parameters, can it be directly used as a class as a constraint? For example, call a static method? Create a class that inherits the parameters of this type in the generic model?

We can find that each of these computations may be a special case, rather than a simple implementation.

For example, to call a static method, T. hello () involves the class T can be clearly defined during execution, and creating a class in a generic class that inherits the parameters of this type will become complicated.

Just think about the method to call that class: MyClass <T>. MySubClass, the syntax here is a bit "not average", not necessarily a "just a problem of generics ".

Is more and more functions a correct path for C # or any language?

 

 

Questions

If you are not satisfied, you can provide the appropriate title to prohibit attacks against authors in any way!

 

 

 

 

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.