C # generic type parameter may be constrained way constructors with parameters of it?

Original: C # generic type parameter may be constrained manner with arguments constructor do?

Review after seeing the title so I am very ashamed of myself poor language skills, it is estimated ... please forgive me ...... I specifically wrote the phrase back to the beginning of the ......

 

 

problem

One problem encountered the day before yesterday, so in MSDN made a asked , just enriches the next question, about generics.

Recent attempts DDD often strange ideas in EF, such as "EF can add the Model First generics support." This is "whether there is a generic type constraint mode with arguments."

Specific idea is very simple, when I use generics, I found 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 above would be an error .

T error content is not a new constraint (new constraint), under review MSDN, get the contents of the new constraints of the generic type parameter .

So the next 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 later I found that I need to create a new object based on the parameters, and the method is implemented in the most appropriate generic constructor, so I hope to have this 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 }

Unfortunately, this case would be very wrong, and then review the generic list constraint way , find a constructor with no parameters of such constraints .

 

So I just happened above in that question on MSDN asking , seeking a "elegant solution."

 

General solution just as problematic answer in two types, but also I tried two very unhappy, we turn to look at.

supplement:

  • By the James.Ying reminders, as well as passing from a constructor
  • Reminded by the @Choo, with Activator.CreateInstance

 

 

Factory Pattern

The first is the Factory Pattern, is to build a factory class, take a look at the code, this is one way to write, do not tangle in the 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 }

Implementation, you will find that this need to create a category for each derived class or instance and maintain a Factory class, as a generic sense in itself is not so great, it has always been to reduce the type of reuse logic and the use of generics .

 

 

Static abstract method of the abstract base class

If you do not want to maintain a multi-class, then the target class is to start, 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 TBase
13 {
14     public abstract static TBase New(string request);
15 }

In order to prevent fraught, first thing to say is ahead, write that compiles wrong!

The constraint is not wrong, but it is similar to the reported error "T is a type parameter, can not be so used!" ( 'T' is a 'type parameter', which is not valid in the given context).

 

 

Incoming from the constructor

There is also a basic approach but forgotten by James.Ying reminded to think of it, is passed from the generic class constructor.

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

    T MyObject { get; set; }
}

Such a way that the generic class more concise, the instantiation process to the caller, a little dependent on the upside (in fact, all that should be implemented and handed over to the caller or successor in generics was like this).

The advantage is generic simple, the disadvantage is that you can not guarantee that instantiated using the constructor is T (string). In addition, it may reduce the reusability of code. Hypothetical Example of a conditional, and logical all derived classes are uniform, it is still better to achieve in a generic base class.

In simple cases this is generic for the most elegant way.

 

 

Activator.CreateInstance

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

Create an instance of a type with the most matching constructor (Creates an instance of the specified type using the constructor that best matches the specified parameters).

Writing is also very interesting:

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

    T MyObject { get; set; }
}

This approach can do, and very brief, it does not do more interfaces and base classes.

Drawback is not binding, there is no way to ensure that T can constructor with the specified number and type of parameters, or whether there is a constructor.

If T does not meet the design requirements will be reported if appropriate exception .

 

 

The original generic type parameter is designed so

At this point, we will know, C # generic, the type parameter is the presence of a "non-Class", the constraint type parameter (Constraints on Type Parameters) are merely used to describe particular classes required when instantiated or inheritance achieve conditions. In the interior of the generic type parameter it is merely a "special existence", which is used to describe the class, but the class can not be used.

 

 

Then, type parameters can have the reference paper entitled ...... ......

First of all, in fact, the problem itself is a generic type parameter can have an example of the way with parameters, such as  T myObject = new new T ( " the Hello World!")  .

Then, since the parameter type is "bound" to describe the way the characteristics of the instance of the class, so that it becomes a problem the generic type parameter can have parameters constructor constraint manner, such as  WHERE T: new new ( String )  .

Do assume, then, is a falsification of the initial problem, it exists to prove whether it will cause any question of principle.

First is able to compare the generic type parameter has been bound manner with no arguments constructor, then even if there is a generic type parameter constraint mode with the parameters of the constructors and how? At least, the generic type parameter has been bound without any arguments constructor proves the generic type parameter constructor constrained manner and will not cause any problems and is technically achievable. (......)

In our example of a new object is initialized when usually in two ways:

  • Using the constructor parameter passing
  • After instantiating assignment

In most cases the result is almost produced in two ways, which in most cases means generally involved the properties or parameters are disclosed in (public), originally open reading and writing, the internal and external write Write They are similar.

But encountered some cases, such as some business constraints, or process parameters needed to operate using parameters, a final operation result is private (Private), it will tend to choose a constructor parameter passing. Or use a special method, after the process by the data class is instantiated then brought required to operate, do little beneath "coherent" refreshing.

Using the constructor parameter passing is not a easy alternative way, because it is the best solution in most scenarios where it belongs . Sometimes, initialize an object to use, all in one is the best, because the transaction itself, there is a strong atomicity. Two kinds of ways to initialize an object has been problematic for double entry as the user of the class, you sometimes blurred, the results generated in two ways that you can not accurately grasp; for developers, for the two implementations appears on the specification also requires either choose one or both to ensure consistency. When the class becomes relatively complicated, things are not so simple.

So, we really need the generic type parameter will have a scene with a number of bound manner constructor parameters. While it is not necessary, but it is definitely a necessity, like get / set accessor that.

 

 

Additionally, in fact larger proposition is the type of argument can be use as a class

It can be assumed that constraint by the constructor with parameters, then can you direct as constrained as to use it as a class? For example, call the static method? Create a class that inherits from type parameters in generics?

All of these operators are likely to be found in every special case, rather than a simple implementation can be resolved.

For example, it calls the static method, T.Hello () is executed when involved in T can clearly which classes; and create a class inherits from the type of the parameter becomes complicated in a generic class.

Just think about calling the class method: MyClass <T> .MySubClass, grammar here a bit "unusual", and may not be a "mere generic problem itself."

He said high force grid by little, more and more functionality is the right path for C # or any one language, it?

 

 

On the topic

If you are dissatisfied, they can provide a suitable title, author prohibited in any way to attack!

 

 

 

 

Guess you like

Origin www.cnblogs.com/lonelyxmas/p/11286112.html