I'm fairly new to Reflection in C#, and I think I understand how to use it to solve some problems.
However, what I find confusing is the syntax for methods like GetProperty() or GetField().
To get an instance field, you have to do typeof(MyClass).GetField("fieldName").GetValue(myClassInstance). Which is not the most straightforward thing.
Wouldn't it make more sense to get instance fields or properties by using something like an extension method? Something like:
myClassInstance.GetField("fieldName").Value
And use the previous example for things like static fields/properties/methods.
It just feels more natural than the first example, where you must pass your class instance.
Again, I am new to Reflection, so there might be some disadvantages I'm overlooking.
To get an instance field, you have to do typeof(MyClass).GetField("fieldName").GetValue(myClassInstance). Which is not the most straightforward thing.
Well, not quite. To get an instance field you have to do fieldInfo.GetValue(myClassInstance).
Sure, starting with the compile-time (indeed, coding-time) knowledge that myClassInstance is a MyClass would mean that the way you get that fieldInfo is through typeof(MyClass).GetField("fieldName") but then one would just do myClassInstance.fieldName or if a cast was necessary ((MyClass)myClassInstance).fieldName which is easier, faster and less error-prone.
Reflection is useful when we can't just do myClassInstance.fieldName because we only obtained the Type and/or the FieldInfo at runtime. What we need then is the flexibility to let us handle a wide variety of cases of just what we do or don't know at compile-time.
Now, it's perfectly possible to create types and methods (instance or extension) such that myClassInstance.GetField("fieldName").Value would work. But how useful would that be?
First, as stated above, it's pointless if we know the type of myClassInstance at compile-time. But also, what type should this GetField() method work on? The compile-time type is clearly pointless, but should it be the run-time type (the type one would find by calling GetType())? That would probably be the most commonly useful type, but we might want to force the lookup to be on a particular base type (or interface type — clearly not in the case of looking up fields, but perhaps for methods, properties and events), so we've lost flexibility in this and gained only for a particular subset of cases currently catered for.
So while adding this functionality would be useful in some cases, the current API would remain necessary in some other cases. It could only be an also convenience API, not the primary one.
And in fact we have that convenience API, for it is what dynamic gives us.
((dynamic)myClassInstance).fieldName
This allows us to get or set the field called fieldName on the runtime-type of myClassInstance and generally is even more convenient than the API you propose. It also has the advantage that the separate compile-time type (at runtime dynamic is the same as object at compile-time the compiler treats it differently at compile-time by using late rather than early binding). So we don't have a public surface on object full of methods for a pretty rare case (and indeed a case that should be rare; the speed, typing of return types and above all guards against incorrectness that come from type safety are to be favoured whenever possible) and also get dynamic as the return type too which is good because we're more likely to want to do more of this sort of late-binding when it's how we obtained an instance the first time.
I am building a simple custom lightweight csv generator class named, oddly enough, CsvWriter<T>.
The way this class works is that it will automatically generate a csv to an underlying Stream from all public properties that are marked with a predefined attribute that we aptly named CsvPropertyAttribute.
Upon object creation I would like to check that the generic type implements at least one public property with the predefined CsvPropertyAttribute. If that weren' the case I'd like to throw an exception as the generic type parameter is not really valid.
The questions that arise are the following:
Is it OK to throw an exception in the constructor? If not the solution would be easy: I could defer the search of valid properties to the first call to WriteLine(T record) or similar mehtod (lazy initialization).
Is it OK to throw an exception caused by a generic type parameter? Or is it just better to leave the generated csv empty? There is no way I can constraint the generic parameter to valid types.
And finally, if answer to question No. 2 is yes, what exception should I use? ArgumentException seems the better fit but its still not quite right.
Thank you.
You can even throw an exception from the class constructor (aka static constructor). That way you can do your checks/initializations only once per T.
If the class constructor fails for CsvWriter<Foo>, you won't be able to even call the constructor of CsvWriter<Foo>.
If you're worried about proper argument typing, you could create a custom exception type. It's the cleanest solution. But I wouldn't worry about it that much since if you use the class constructor, your exception will be wrapped in a TypeInitializationException either way.
This is really something that should be a compile-time error, but the language doesn't support it.
1: Yes, go ahead and throw in the constructor. This fail-fast technique will make it less likely you ship bad code.
2: Throw as soon as possible. Don't create the file.
3: I'd create a subclass of InvalidOperationException. You may think of something better.
Also, I highly recommend writing a unit test not only for this class, but for any other code that ever instantiates it.
You may also want to re-think your design. Maybe an interface to give you the basics.
I recall reading an article about constructors being evil (but can't place it). The author mentioned that constructors are a special case of methods; but have restrictions (such as that they cannot have a return value).
Are constructors evil? Is it better to have no constructors and instead rely on a method like Initialize, along with default values for member variables?
(Your answer can be specific to C# or Java, if you must pin down a language.)
That sounds like Allen Holub. One might argue that constructors are evil solely to drive web traffic :) They are no more evil than any other language construct. They have good and bad effects. Of course you can't eliminate them -- no way to construct objects without them!
What you can do, though, and this is the case that Allen was making, is you can limit your actual invocation of them, and instead favor, when sensible, factory methods like your Initialize. The reason for this is simple: it reduces coupling between classes, and makes it easier to substitute one class for another during testing or when an application evolves.
Imagine if your application does something like
DatabaseConnection dc = new OracleDatabaseConnection(connectionString);
dc.query("...");
and imagine that this happens in a hundred places in your application. Now, how do you unit test any class that does this? And what happens when you switch to Mysql to save money?
But if you did this:
DatabaseConnection dc = DatabaseConnectionFactory.get(connectionString);
dc.query("...");
Then to update your app, you just have to change what DatabaseConnectionFactory.get() returns, and that could be controlled by a configuration file. Avoiding the explicit use of constructors makes your code more flexible.
Edit: I can't find a "constructors" article, but here's his extends is evil one, and here's his getters and setters are evil one.
They aren't. In fact, there is a specific pattern known as Inversion of Control that makes ingenious use of Constructors to nicely decouple code and make maintenance easier. In addition, certain problems are only solvable by using non default constructors.
Evil? No.
Calling a constructor does require that you call "new", which does tie you to a particular implementation. Factories and dependency injection allow you to be more dynamic about runtime types, but they require programming to interfaces.
I think the latter are more flexible, but constructors evil? That's going too far, just like having an iterface for everything goes too far.
Constructors aren't evil, but (at least in Java) often it's better to use static Factory methods instead (which of course use constructors internally).
Here are a few quotes From Effective Java, Item 1: Consider static factory methods instead of constructors:
One advantage of static factory
methods is that, unlike constructors,
they have names. If the parameters to
a constructor do not, in and of
themselves, describe the object being
returned, a static factory with a
well-chosen name is easier to use and
the resulting client code easier to
read.
...
A second advantage of static factory
methods is that, unlike constructors,
they are not required to create a new
object each time they’re invoked. This
allows immutable classes (Item 15) to
use preconstructed instances, or to
cache instances as they’re
constructed, and dispense them
repeatedly to avoid creating
unnecessary duplicate objects.
...
A third advantage of static factory
methods is that, unlike constructors,
they can return an object of any
subtype of their return type.
...
A fourth advantage of static factory
methods is that they reduce the
verbosity of creating parameterized
type instances. Unfortunately, you
must specify the type parameters when
you invoke the constructor of a
parameterized class even if they’re
obvious from context. This typically
requires you to provide the type
parameters twice in quick succession:
Map<String, List<String>> m =
new HashMap<String, List<String>>();
...
The main disadvantage of providing
only static factory methods is that
classes without public or protected
constructors cannot be subclassed.
...
A second disadvantage of static
factory methods is that they are not
readily distinguishable from other
static methods.
Constructors allow initialization lists and other useful things. There's no way to dynamically initialize an object in an array (that doesn't use pointers to objects) without a copy constructor.
No they aren't evil.
They are special cases.
Constructors are not evil. They exist so that code can be run when an instance of a class is initialized. Just as with any other programming concept, if they aren't used right they can be a disaster to work with. But, if used correctly, they can be a great (and essential) tool.
http://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)
I wouldn't say constructors are evil.
Constructors return a reference to the Object you are instantianting and should be used to set an object up to a default state. I can see benefits of using an Initialize method but there isn't much point. UNLESS you need to initialize some logic AFTER the object has been allocated stack space and initial values.
Constructors are not evil. Whatever article you read is wrong and you're better off having forgotten the link.
Constructors are not evil nor are they good. Constructors are a tool that can be very helpful if used properly and in the correct context. In fact at least in .NET languages such as C# if you do not explicitly declare a constructor in your code a constructor will be created for you by the compiler with no functionality.
Constructors are good when following normal OO programming paradigms. There are situations where you might need to place extra constraints on how objects are created, so in some cases a Factory pattern with private ctors might be a better fit. There is also a philosophy/best practice that says object instantiation should be the same as initialization, in which case constructors are the only real option outside factories that you have.
(factories still use constructors internally of course)
The question may not be about constructors in Java or C#, but constructors in javascript. In Javascript constructors can be a source of subtle errors. A lot of Javascript books recommend that beginners steer clear of constructors.
For a more detailed discussion of the evilness of constructors, and the new keyword, in javascript look : Is JavaScript's "new" keyword considered harmful?
I picked up this sort of vibe, to a degree, from Miško Hevery's talk "Don't look for things" which is available on YouTube. Part of the outlining discussion he gives, I interpret as a criticism of 'fat constructors', if not constructors in general.
The point of this argument, at least as I understood it, was that constructors that take in everything the object wants encourage you to enforce correctness using the constructor, instead of enforcing correctness with tests. Constructors do tend to bloat to do exactly that, so if this bothers you, you could consider it an evil streak in the concept of the constructor. In the talk he says he prefers to only require an object to 'have' another object when it's needed to do something, rather than requiring it on construction.
Here's one article that considers whether constructors are harmful, not "evil". It's mostly in the context of JavaScript/Es6 but the arguments may hold for any language which has constructors.
The argument is really about user-defined constructors, you still need to call the system provided default constructors, else you could not create any instances at all.
The simplest argument is that if you can do the same thing with static methods as with custom constructors, isn't it better to choose one of the approaches and always stick to that, except if there is a specific reason not to.
That makes your program simpler in total and thus less error-prone. Note that Smalltalk never had "constructors".
https://medium.com/#panuviljamaa/constructors-considered-harmful-c3af0d72c2b1
Is there ever a reason to use Type parameters over generics, ie:
// this...
void Foo(Type T);
// ...over this.
void Foo<T>();
It seems to me that generics are far more useful in that they provide generic constraints and with C# 4.0, contravarience and covarience, as well as probably some other features I don't know about. It would seem to me that the generic form has all the pluses, and no negatives that the first doesn't also share. So, are there any cases where you'd use the first instead?
Absolutely: when you don't know the type until execution time. For example:
foreach (Type t in someAssembly.GetTypes())
{
Foo(t);
}
Doing that when Foo is generic is painful. It's doable but painful.
It also allows the parameter to be null, which can be helpful in some situations.
Well they really aren't the same at all.
With the second one, you've actually got a class of the compile-time type there (whatever has been passed in by whoever). So you can call specific functions on it (say if it's all of some given interface).
In your first example, you've got an object of class 'Type'. So you'll need to still determine what it is and do a cast to do anything useful with it.
Foo(someVariable.GetType()); // allowed
Foo<someVariable.GetType()>(); // illegal
From a design perspective, I wonder why the .NET creators chose System.Object.GetType() instead of a System.Object.Type read-only property.
Is it just a (very minor) design flaw or is there rationale behind there?
Any lights welcome.
If you look at the GetType() declaration in Reflector you'll find this:
[MethodImplAttribute(MethodImplOptions.InternalCall)]
public extern Type GetType();
What that combination of attribute and extern means is that this method is actually implemented in unmanaged code inside the .NET runtime itself. The GUID question in this article goes into further details. They obviously did this for performance reasons after determining that figuring out the Type would be faster if handled at a lower level.
This leads to two reasons not to implement the GetType method as a property. Firstly you can't define properties extern as you can with methods, so it would need to be handled in native .NET code. Secondly even if you could define them as extern, performing an unsafe, unmanaged call from inside a property would definitely break the guidelines for property usage since it's much harder to guarantee that there are no side effects.
The guidelines say that a property should represent a state of the object, it should not be expensive performance wise, and it should not have side effects apart from computing/setting that state. My guess is GetType() does not respect these rules so they made it a method.
GetType() is a slightly expensive operation. If it were a property it would encourage uses like
DoStuff(obj.Type);
....
DoStuff(obj.Type);
etc.
instead of
Type type = obj.GetType();
DoStuff(type);
....
DoStuff(type);
and that would be not so optimal. So they made it a method to suggest that it should be called sparingly.
As I understand it, it is in general considered good practice for internal fields or values which are trivial to calculate to be exposed using a property, and other values, which may require more time or other resources to calculate, to be exposed using a method.
Only Microsoft can answer that question, but I think it's because several classes in the .NET Framework create their own overloaded versions of GetType() with extra parameters. If it would have been a property, they couldn't use the same name (because properties don't have parameters).
Just my thoughts on the subject.
A bit late reply but crashed into the question while trying to find something related.
It is possible for GetType to throw an exception. Framework guidelines state that properties should not throw exceptions. This is one more reason why it should be a method instead of property.