Trouble understanding "Generics" example - c#

I am going through a book trying to understand Generics with C# and I have come across an example I don't understand. Here is the sample code.
using System;
public class Printer
{
public void Print<T>(T argument)
{
Console.WriteLine(argument.ToString());
}
static void Main(string[] arguments)
{
Printer printer = new Printer();
printer.Print<string>("Hello, World");
Console.WriteLine("Done");
Console.ReadKey();
}
}
What is confusing me is the argument to the Print method. I understand using a generic type placeholder when dealing with a collections such as List<T>. However what I don't understand is how <T> comes into play with a method? Is the code just saying that the type of the parameter passed into the Print() method is just not known at design time and could be anything? Could someone help me decipher this? Thank you.

By declaring your method with a generic type, you make your method more flexible as it can then work with variables of any type you choose, including primitive types (unless you specify where T : class of course).
Another very common example that much better illustrates one use of a generic method is a Swap<T>(T, T) method:
/*
* The ref keywords mean "pass by reference" i.e. modify the variables as they
* were passed into the method.
*
* The <T> in the signature tells the compiler that T is a generic type, in case
* the class itself doesn't already declare T a generic type.
*/
public void Swap<T>(ref T x, ref T y)
{
// Tells the compiler that temp should be of the same type as x and y,
// regardless of what type T may be
T temp = x;
x = y;
y = temp;
}
int x = 3, y = 6;
Swap<int>(ref x, ref y);
Console.WriteLine(x + " " + y);
char a = 'a', b = 'b';
Swap<char>(ref a, ref b);
Console.WriteLine(a + " " + b);

Exactly what you wrote. Generic parameters are also possible at method level. They act exactly like on class level, just the scope of the type parameter is limited to the method.

Is the code just saying that the type of the parameter passed into the Print() method is just not known at design time and could be anything?
That's precisely what it's saying. Now, whenever the compiler finds a reference to a T it will automagically substitute the type that was specified in the instance or method call (if the method is generic). A prime example of that type of method is a pattern I've used (and seen used) many times. It's basically a safe cast from one type to another. The type you want to coerce to is specified as the generic parameter. Example:
var something = SafeCast<int>("123.434"); // something == 123
var somethingElse = SafeCast<int>(23.45f); // somethingElse == 23
var somethingNull = SafeCast<int>(null); // this shouldn't throw but return a null

As the compiler does not know what T is, and T isnt defined at class-level, then the compiler needs to know what to cast the parameters to, thats where the argument comes into play ;)

Related

C# compiler type inference with dynamic function parameters

When I call a function and replace one of the parameters with dynamic, the compiler inferres the function result to be dynamic. I don't understand why this happens.
Example: the inferred type for a is dynamic, so this code compiles, but of course fails at runtime with RuntimeBinderException:
dynamic b = "";
var a = MethodWithoutOverloads("", b);
a.DoesNotExist();
...
public string MethodWithoutOverloads(string a, string b) { ... }
Somebody knows why the type inferred is not the return type of the function?
EDIT: edited to make clear this happens with methods without overloads
You are right in the sense that the compiler could reason out that all String.Format overloads return a string and therefore infer that a must be a string no matter what b really is.
The truth is that the compiler does not do that. It solves the general case, which is good, and because overloads with different return types are valid in C#, it simply assigns the return type as dynamic and lets the runtime figure it out.
Answering your specific question,
public string MethodWithoutOverloads(string a, string b) { ... }
dynamic a = "";
var result = MethodWithoutOverloads(a, a); // result is dynamic.
Lets imagine the compiler decides that result is string and you publish to the wild west your library. Then, later on, you decide to add an overload with the following signature:
public int MethodWithoutOverloads(int a, int b) { ... }
Now, what should the type of result be? And, what happens to existing code that relied on result being strongly typed to string?
string result = MethodWithoutOverloads(someDynamicVariable, someOtherDynamicVariable);
The semantics change completely; before a consumer had a safe strongly typed variable, now he suddenly has a potentially unsafe implicit cast that can blow up in runtime.
Because the compiler doesn't know which method is going to be invoked at run time.
For example, you may have the two methods:
int MyMethod(int a)
{
return 5;
}
double MyMethod(string a)
{
return 6.0;
}
And you write the following code:
dynamic myThing = 5;
var myResult = MyMethod(myThing);
Considering we've explicitly said myThing is dynamic, and this its type is to be determined at runtime, we have no idea which method will be invoked (if any). Thus, we don't know the return type, either.

Is there a technical reason for requiring the "out" and "ref" keywords at the caller?

When calling a method with a ref or out parameter, you have to specify the appropriate keyword when you call the method. I understand that from a style and code quality standpoint (as explained here for example), but I'm curious whether there is also a technical need for the keywords to be specified in the caller.
For example:
static void Main()
{
int y = 0;
Increment(ref y); // Is there any technical reason to include ref here?
}
static void Increment(ref int x)
{
x++;
}
The only technical reason I could think of is overload resolution: you could have
static void Increment(ref int x)
and also
static void Increment(int x)
This is allowed; without ref in the call, the compiler wouldn't be able to tell them apart.
If you're asking whether the language could have been designed so that those aren't needed at the call site, the answer is yes. There is no particular reason they could not have been left out. The compiler has all the information it needs from the metadata, so it could make the proper transformation.
That said, doing so would have made it impossible to have these two overloads:
public void DoSomething(int x);
public void DoSomething(ref int x);
The compiler wouldn't be able to disambiguate that.
Although the ref and out could have been made optional, in which case those overloads would be allowed. And the compiler could either take the default (i.e. the non-ref), or issue an ambiguity error and make you specify which one you really wanted.
All that said, I like having to specify ref and out at the call site. It tells me that the parameter could potentially be modified. Having worked in Pascal for many years, where a var parameter is passed the same way that a value parameter is passed (the syntax at the call site is the same), I much prefer the specificity of C# in that regard.
Another reason to require the modifier is to make changing a parameter to a ref or out a breaking change. If the ref/out could be inferred, then an evil programmer changing a parameter from by-value to by-reference would not be detected by clients compiling against the new signature. If a client called the method
public int Increment(int x)
{
return x + 1;
}
by using
int result = Increment(x);
Suppose an evil developer decided to change the implementation to instead change the value passed by reference and return an error code if, say, the increment resulted in an overflow:
public int Increment(ref int x)
{
x = x + 1;
if(x == int.MinValue) // overflow
return -1;
else
return 0;
}
Then a client building against the signature would not receive a compile error, but it would almost certainly break the calling app.
The compiler needs to know the method parameters it is interpreting when it is building IL.
One reason is having overloads like:
public void (ref int x) {}
public void (int x) {}
Another reason is out will explicitly allow you to use pass-by-value parameter use the interpreted value outside the method. ref will give the pointer to the parameter thereby pointing any new value from the method to the same memory location

How to pass an arbitrary function with some bound parameters to another function?

I have a generic function CallLater that should accept an arbitrary other function and possibly call it later with some parameters. All kind of functions should be supported - static, instance, private, public. Parameters are analyzed and constructed dynamically in CallLater with the help of reflection. However, some of them may need to be bound to fixed values before passing the function to the CallLater.
For example:
void CallLater(Delegate d) {
// Expects a function that returns string and has one argument of arbitrary type.
if (d.Method.GetParameters().Length == 1 &&
d.Method.ReturnType == typeof(string)) {
object param1 = Activator.CreateInstance(d.Method.GetParameters()[0].ParameterType);
Console.WriteLine((string)d.DynamicInvoke(param1));
}
}
// Has one extra float parameter.
string MyFunc(int a, float b) { ... }
My idea was to do something like that:
float pi = 3.14f;
CallLater(delegate(int a) { return MyFunc(a, pi); });
But this doesn't work as compiler complains:
Error CS1660: Cannot convert `anonymous method' to non-delegate type `System.Delegate' (CS1660) (test-delegate)
What is the correct approach to achieve my goal?
P.S. Please do not offer the solution to declare a fixed delegate type as CallLater is way more complex and may support variable number of arguments too.
P.P.S. It might be that my solution is Func, but I wasn't able to use it on Mono so far.
You can always redeclare Func yourself:
public delegate TReturn FFunc<TArg,TReturn>(TArg arg);
Which you can use thusly:
float pi = 3.14f;
CallLater((FFunc<int,string>)(delegate(int a) { return MyFunc(a, pi); }));
I'd suggest using anonymous functions in which you call the method you want to execute. These are executed later when the anonymous method is executed.
private static void ExecuteBoolResult(Func<bool> method)
{
bool result = method();
if (!result)
{
throw new InvalidOperationException("method did not return true");
}
}
CheckBoolResult(() => AnotherFunction("with ", 3, " parameters"));
CheckBoolResult(() => AnotherFunction(2, "parameters"));

C# reflection and instantiation - is there a way to do Activator.CreateInstance(myType){ X = x }?

I'm not sure of the terminology for this kind of code, but I want to know if it's possible to instantiate variables after the parentheses, but whilst using reflection.
I have a map which gets loaded from an XML file. This is a collection of (int X, int Y, string S) where the X,Y is the position of some terrain, and S is a string representing the type of the terrain. I have a dictionary to pass between the strings and the relevant types; for example one key-value pair might be "Tree", typeof(Tree).
When using reflection, although I know it's possible to instantiate with parameters, the only way I'm comfortable is just by using Activator.CreateInstance(Type t), i.e. with an empty constructor.
When I had the maps hard coded, I would originally instantiate like this (within some i,j for loop):
case: "Tree"
world.Add( new Tree(i,j) );
Whilst starting to think about reflection and my save file, I changed this to:
world.Add( new Tree() { X = i, Y = j }
However, I realised that this won't work with reflection, so I am having to do the following (Tree inherits from Terrain, and the dictionary just converts the XML save data string to a type):
Type type = dictionary[dataItem.typeAsString];
Terrain t = (Terrain)Activator.CreateInstance(type);
t.X = i;
t.Y = j;
world.Add(t);
I would prefer to do this using something like
Type type = dictionary[dataItem.typeAsString];
world.Add((Terrain)Activator.CreateInstance(type) { X = i, Y = j }
Is there any shortcut like this? I guess if not I could edit world.Add to take an X and Y and cast to Terrain in there to access those variables, but I am still curious as to a) what this {var1 = X, var2 = Y} programming is called, and b) whether something similar exists when using reflection.
This syntax is called Object Initializer syntax and is just syntactic sugar for setting the properties.
The code var result = new MyType { X = x } will be compiled to this:
MyType __tmp = new MyType();
__tmp.X = x;
MyType result = __tmp;
You will have to do that yourself using PropertyInfo.SetValue if you know the instantiated type only at runtime or use the normal property setters if the type is known at compile time.
The answer is no, because the object initialization syntax you mention (introduced with LINQ in 3.0) is an illusion of the compiler. As in, when you type this
var foo = new Foo { Bar = "baz" };
the compiler actually converts it into CLS-compliant IL which equates to
var foo = new Foo();
foo.Bar = "baz";
Phil Haack has a great blog post which not only covers the details of this rewriting done by the compiler, but also some side effects it can cause when dealing with types that implement IDisposable
As all of this is nothing but a feint by the compiler, there is no equivalent using reflection (i.e., Activator.CreateInstance(Type t)). Others will give you workarounds, but in the end there really is no direct equivalent.
Probably the closest generic hack you could manage would be to create a method that accepted an object, then used reflection in order to identify the properties of that object and their respective values in order to perform object initialization for you. It might be used something like this
var foo = Supercollider.Initialize<Foo>(new { Bar = "baz" });
and the code would be something like (this is off the top of my head)
public sealed class Supercollider
{
public static T Initialize<T>(object propertySource)
{
// you can provide overloads for types that don't have a default ctor
var result = Activator.CreateInstance(typeof(T));
foreach(var prop in ReflectionHelper.GetProperties(typeof(T)))
ReflectionHelper.SetPropertyValue(
result, // the target
prop, // the PropertyInfo
propertySource); // where we get the value
}
}
You'd have to get each property from the anonymous object, find a property in your target type with the same exact name and type, then get the value from that property in the anonymous object and set the value of your target's property to this value. Its not incredibly hard, but its absolutely prone to runtime exceptions and issues where the compiler chooses a different type for the anonymous type's property, requiring you be more specific (e.g., new { Bar = (string)null }), which screws with the elegance of the thing.
(T)Activator.CreateInstance(typeof(T), param1, param2, ...);
As described HERE.
public sealed class ReflectionUtils
{
public static T ObjectInitializer<T>(Action<T> initialize)
{
var result = Activator.CreateInstance<T>();
initialize(result);
return result;
}
}
public class MyModel
{
public string Name{get;set;}
}
And after that just make the call :
var myModel = ReflectionUtils.ObjectInitializer<MyModel>(m =>
{
m.Name = "Asdf"
});
The advantage is that in this way you will have type safety and use reflection as minimum required, because we all know that reflection is an expensive operation that should be avoided as much as possible.
You could create a constructor which takes those arguments, then use
Activator.CreateInstance(type, i, j)
But you won't be able to use the object initialization syntax. Which is just sugar candy for setting the properties.

Using out keyword in c#

can anyone suggest me the exact use of out keyword as a paramter, and how its connected for returning multiple values from the function, as in this POST, i am confused with out variable with normal variable. can anyone help me for this.
This is frequently confusing, and I think the MSDN documentation actually is a bit "clear only if already known". That is, it is correct, but it really only makes sense if you already understand the concept.
Here's how I think of it.
A regular parameter makes a copy of the value of the argument. When you say:
static int M(int z) { z = z + 1; return z; }
...
int x = 123;
int y = M(x);
That is just like you said:
int x = 123;
int z = x; // make a copy of x
z = z + 1;
int y = z;
A ref or out parameter make an alias for an existing variable. When you say
static void N(ref int q) { q = q + 1; }
...
int x = 123;
N(x);
That is the same as saying:
int x = 123;
// MAGIC: q is now an another name for variable x
q = q + 1;
q and x are two different names that refer to the same variable. Incrementing q also increments x because they are the same. z and x in the previous example are two different names that refer to two different variables. Incrementing z does not change x.
Summing up: "out" and "ref" just mean "do not make a new variable; rather, temporarily make a second name for an existing variable".
Is that now clear?
UPDATE: I did not say what the difference between "out" and "ref" is. The difference is simple. On the "caller" side, a "ref" must be a definitely assigned variable before the method is called. An "out" need not be. On the "callee" side, a "ref" may be read before it is written to, but an "out" must be written to before it is read. Also, an "out" must be written to before control leaves the method normally.
MSDN documentation already does a great job explaining this:
The out keyword causes arguments to be passed by reference. This is
similar to the ref keyword, except that ref requires that the variable
be initialized before being passed. To use an out parameter, both the
method definition and the calling method must explicitly use the out
keyword. For example:
class OutExample
{
static void Method(out int i)
{
i = 44;
}
static void Main()
{
int value;
Method(out value);
// value is now 44
}
}
It's very frequently used in a pattern that "tries" to get a value, something like:
int result;
if(Int32.TryParse("123", out result))
{
Console.WriteLine(result + 1);
}
out keyword should be used when you want to:
a) Allow your function to modify specific variable from calling code stack AND
b) enforce setting this variable value inside your function
MSDN is always a good place to start
In most languages c# included you can pass values in 2 ways, by value, by reference.
by value gives the method a copy of your data, so changing the data wont have any effect on the original data
by reference essentially gives the method the memory address of your data, so if the method modifies the data, it changes the original.
Out is a special type of ref, in that you do not need to initialise the variable before you call the method, it can be called with null being passed in. and it MUST be set by the method.
Another way you can think of it (from the outside code's point of view) is:
val = read only
ref = read/write
out = write only.
http://msdn.microsoft.com/en-us/library/t3c3bfhx(v=vs.80).aspx
out keyword is good if you want to return multiple values of pre-defined types (for example an int, a List<string> and a DateTime), and you don't want to create a new class just for this purpose.
Ok,
let look at the usual pattern for this kind of function - the TrySomething.
Suppose you have a function that might succeed giving you an value or not but you don't won't to use an exception for this because you don't want the overhead or it's a common trait.
Then you normaly return true if the method suceeded and false if not. But where would you put your outputvalue to?
One possible answer is using an out parameter like this:
bool TrySomething(MyInputType input, out MyOutputType output)
{
output = default(MyOutputType);
/* ... Try getting the answer ... */
if (!successful)
return false;
output = successfulOutput;
return true;
}
Remark:
Or you might consider using a Tuple<bool,MyOutputType> and indeed F# interpretes the pattern above as resulting in such a tuple by itself.

Categories

Resources