Objects generated by different parameter types of generics are independent of each other.
//likeTuple<string> ts; Tuple<object> to; //ts to Are two types of objects。
Many times, we want to implement the operation to = ts, why? Because it looks like it should be.
In order to achieve this goal, we must solve the "problem of generic parameter conversion". The knowledge point of this problem is in out generic variant. To be honest, this problem itself is not difficult, it is just very unintuitive and easy to forget.
First of all, in order to implement to = ts, there is actually a prerequisite, that is, this parameter can only be used on the "return type".
//likedelegate object FuncObj(); FuncObj func = ()=>"string";
The reason why func is successful is that string can be converted into object. When the "user" calls func, what you want is the object object, and string is also the object object, so there is no problem.
The key here is to learn to analyze problems from a "user" perspective.
//A delegate void FuncObj2(object obj); FuncObj2 func2 = (string str)=>{}; //B delegate void FuncStr(string str); FuncStr func3 = (object obj)=>{};
Which of the two sets of codes is more reasonable?
From the user's perspective, it uses func2 and func3
When the user uses func2, the object passed must be an object, but the actual processing function is (string)=>{}, and the object cannot be converted into a string, so it is very unreasonable.
When users use func3, the object passed can only be a string, and the actual processing function is (object)=>{}, string can be converted to object, so it is reasonable.
Of course, both sets of codes are not valid because the function parameter types do not match.
But generics provide a way to enable implicit conversion between objects with type mismatch! The logic of its implementation is analyzed above.
//out Modify return typedelegate ResultType FuncOut<out ResultType>(); //in Modify parameter typedelegate void FuncIn<in ParamType>(ParamType param); //This is the goal we wanted to achieve at the beginningFuncOut<object> fun4 = () => "string"; //This effect is exactly the oppositeFuncIn<object> funcobj = (object obj) => { }; FuncIn<string> fun5 = funcobj; //Note that generic variants can generally only be converted implicitly between generic variants//The lambda expression will automatically convert into a generic variant with the same parameters, but it cannot be followed by implicit conversion between variants, so funcobj is needed to transition
The out modifies the return type and the in modifies the parameter type are quite vivid, but you should pay attention to the generic in parameters, which is exactly the opposite of the out parameter.
At first we wanted to implement to = ts, but we only saw half of the problem. In fact, generics have the possibility of ts = to, and I hope the readers can understand this.
Summarize:
out : to = ts;
in : ts = to;
No modification: to, ts is completely independent.
---------------------------(Remark)-------------------------------
out parameter: can only be used in return type.
in Parameters: Only used in parameters.
No modification: anywhere.
--------------------------------------------------------------------------------------------------------------------------------
In and out generic parameters can only be used on delegates and interfaces.
//Comprehensive applicationdelegate ResultType FuncInOut<in ParamType, out ResultType>(ParamType param); FuncInOut<object, string> funcobj2 = (object obj) => "string"; FuncInOut<string, object> func6 = funcobj2;
The above is all the content of this article. I hope that the content of this article will help you study or work. I also hope to support me more!