C# reflection to check method body of assignment to fields - c#

For the class below :
class A
{
private List<int> intList;
private List<bool> boolList;
public InitializeClass()
{
intList = new List<int>();
}
}
I want to use reflection to write a linter/post compiler of sorts, to check if a certain method really have any assignment to the class' fields or not. The purpose is to automatically check my own errors. The class cannot use constructor, so I need to call InitializeClass() manually.
I have MethodInfo method and all fields of class FieldInfo[] fields that I wanted to check already but have no idea how to go from here. From the example above, it should be able to detect that I haven't assign anything to boolList in the method body.

I ended up reading the code file directly using regular expression.
The file has some constraint, that is it can contains unlimited methods but each method cannot contain any brackets. (No if, etc.)
Then I use "({)(.*)(})" and choose the 2nd group to eliminate class's bracket, then from that I used "{(.*?)}" and iterate through matches for each method's body. (I don't care about method's name actually, I want to check the entire file) After that I read the method's content line by line and split things with characters like '=' or '.'

Related

How to return contents of a List<char>

public List<char> Columns(String input)
{
char[] temp = input.ToCharArray();
List<char> columns = new List<char>(input.Length);
for (int i = 0; i < input.Length; i++)
{
if (other.Contains(temp[i]))
{
columns.Add((char)(i+1));
}
}
return columns;
}
My goal here was to have this method return a List. However, when I went to output the contents in another method I got 'System.Collections.Generic.List[char]
Console.WriteLine(ex.Columns(line));
That was my attempt to output it.
First, let's answer the question of why you get System.Collections.Generic.List[char].
The method you are using to output something to the console is Console.WriteLine. If you go to the linked page you will see many overloads of that method, all taking different kinds of parameters. Let's think which one is being used when you pass an argument of type List<char>.
If you look carefully in that list, you will see that there is no overload that takes List<anything>. As you know, in .NET every type derives from System.Object, or in other words, every type is a kind of System.Object. When the C# compiler tries to choose a method overload, and it fails to resolve the exact type, it reverts to look for is a kind of relationship. In our case, the only overload that matches is the one that takes System.Object.
So what does this overload do? If you read the description you will easily figure it out.
If value is null, only the line terminator is written. Otherwise, the ToString method of value is called to produce its string representation, and the resulting string is written to the standard output stream.
Okay, so when you pass your list of characters, it will call a ToString() method on it. Let's take a look at the ToString() method on the List<T>. When you click on the "ToString" link you will see that you end up on System.Object.ToString() page. This means that the List type doesn't override the base method. So what does the Object.ToString() do?
The default implementation of the ToString method returns the fully qualified name of the type of the Object, as the following example shows.
Mystery solved!
When you write Console.WriteLine(ex.Columns(line)); the compiler invokes the Console.WriteLine(Object) overload which calls Object.ToString() on the passed parameter, which prints the fully qualified name of the type.
Armed with this knowledge, you can figure out what to do in order to print the characters themselves. For example you can pass an array of characters to invoke the Console.WriteLine(Char[]) overload by writing Console.WriteLine(ex.Columns(line).ToArray());
Not sure what you are trying to accomplish here. A string can always be indexed to get a specific character.
So why introduce a List and why have a funky method. Just do:
s[i]
No an array would not help you. To output the contents of a collection you need to loop through each element in the collected.
Using list.ToString() calls the ToString() on on List<T> which calls the standard object ToString implementation , which is to print out the type's name, which is what you are seeing.
You must iterate over it and access each element instead:
foreach(var item in list) {
string s = item.ToString();
}
Try this:
Console.WriteLine(new string(ex.Columns(line).ToArray()));

Implementation of `Class` like `String` Class

I want to implement class i.e. we have String class in .Net. In that, if you check when we code....
C#:
String strString = "Value-12346- .";
String[] strArray = strString.Substring(0, strString.Length - 1).TrimEnd().ToUpper().Split("-".ToCharArray());
in this example if you check we are calling multiple functions of String Class, over each function i.e over Substring function TrimEnd is called and over TrimEnd Split function is called. I would like to implement similar. Please help me out.
Many Thanks!!!
Make sure every method returns an object of the same type (or the type you want) and then you can call the methods on the object like that ( cascade or chain). Each of the above method in the string example returns a new string ( note that strings are immutable here ), so you can apply the string functions again and so on.
On a related note, see how Fluent Interface works. The C# example showing non-fluent and fluent API is a good example: http://en.wikipedia.org/wiki/Fluent_interface
public IConfigurationFluent SetColor(string newColor)
{
this.color = newColor;
return this;
}
As manojlds pointed out above, you achieve that by making your class' member methods return the type of their owner class. Now, in particular, the String's methods return a new string instance every time (instead of "modifying" the source and returning it), so you might want in your methods to create a deep copy of "this" and then made any changes to the new object and return it. Not only that, but the String class is immutable.
Sorry for being too detailed.

Why doesn't C# allow for global inferred types i.e. using var?

I know it can't be done since using var can only be done for local variables. I'm just wondering if anyone has a theory why the C# team thought this should be so. e.g. what would be wrong with this:
public class SomeClass
{
var someString = "hello"; //not cool
public SomeClass()
{
var someOtherString = "hello"; //cool
}
}
If someString is initialised then it is obviously a string just like someOtherString. Why is there one rule for local variables and another for globals?
Duplicate, hence CW.
See the posting by Eric Lippert:
Let me give you a quick oversimplification of how the C# compiler works. First we run through every source file and do a "top level only" parse. That is, we identify every namespace, class, struct, enum, interface, and delegate type declaration at all levels of nesting. We parse all field declarations, method declarations, and so on. In fact, we parse everything except method bodies; those, we skip and come back to them later.
[...]
if we have "var" fields then the type of the field cannot be determined until the expression is analyzed, and that happens after we already need to know the type of the field.
Its to do with the amount of searching the compiler would have to do resolve the type.

Optional parameters

I've got a method that takes a bunch of optional parameters and I'm overloading the method to supply the different combinations of signatures. Intellisense pops up with a bunch of different signatures but I think it looks quite confusing now because there are different combinations I need to provide, not just building up parameters on the end of the method signature.
Should I just not overload my method and stick to one signature so that the user of my method has to pass in nulls? It would make the signature clearer but makes the calling code look messier.
Are you restricted to using C# 1-3? C# 4 supports optional parameters and named arguments...
Until then, you should probably either stick with overloading or create a separate class with mutable properties, e.g.
FooOptions options = new FooOptions { Name="Jon", Location="Reading" };
Foo foo = new Foo(options);
That can all be done in one statement if you want... and if some of the properties are mandatory, then create a single constructor in FooOptions which takes all of them.
In C# 4 you'd be able to write:
Foo foo = new Foo(name: "Jon", location: "Reading");
if the constructor was written as
public Foo(string name,
int age = 0,
string location = null,
string profession = null)
Named arguments and optional parameters should make it a lot easier to construct immutable types with optional properties in C# 4 :)
Think about params argument of c# method.
void test(params object []arg) {
..
}
You could use the params keyword if the function definitions only vary in length (and not order, otherwise this wont be the best approach).Then in the function you can setup the values you need based on the parameter input

C# what is the point or benefit of an indexer?

Doing some code reading and stumbled upon this snippet that I haven't seen before:
public SomeClass {
public someInterface this[String strParameter] {
get {
return SomeInternalMethod(strParameter);
}
}
}
It looks like it is called as follows:
SomeClass _someClass = new SomeClass();
SomeInterface returnedValue = _someClass["someString"];
I am interested in where this function would be appropriate or what the intent of writing in this style. For example why would this be preferred over simply calling the function?
See the language specification, section 10.9, which states:
An Indexer is a member that enables an object to be indexed in the same way as an array.
Indexers and properties are very similar in concept, but differ in the following ways:
A property is identified by its name, whereas an indexer is identified by its signature.
A property is accessed through a simple-name (§7.5.2) or a member-access (§7.5.4), whereas an indexer element is accessed through an element-access (§7.5.6.2).
A property can be a static member, whereas an indexer is always an instance member.
A get accessor of a property corresponds to a method with no parameters, whereas a get accessor of an indexer corresponds to a method with the same formal parameter list as the indexer.
A set accessor of a property corresponds to a method with a single parameter named value, whereas a set accessor of an indexer corresponds to a method with the same formal parameter list as the indexer, plus an additional parameter named value.
It is a compile-time error for an indexer accessor to declare a local variable with the same name as an indexer parameter.
In an overriding property declaration, the inherited property is accessed using the syntax base.P, where P is the property name. In an overriding indexer declaration, the inherited indexer is accessed using the syntax base[E], where E is a comma separated list of expressions.
It seems like a lot of the answers are focusing on what an indexer is, not why you would want to use one.
As far as I'm concerned, here is the motivation to use an indexer:
You are working on a class that has a collection of some sort, but you want the class to appear to users (consumers of the class) as if it is a collection.
The best example I can think of is the DataRow class in ADO.NET. If you want to get the value of the fifth cell of a DataRow, you can either use DataRow.Item[4] or DataRow[4]. The latter form is a convenient and logical shortcut, and it shows off pretty nicely why you'd want to use an indexer. To the user, the DataRow can be thought of as just a collection of cells (even though it is really more than that), so it makes sense to be able to get and set cell values directly, without having to remember that you are actually getting/setting an Item.
Hope that helps.
In many cases, the 'index' syntax makes a lot of sense. It is particularly useful if the SomeClass represents some sort of collection.
It allows you to do associative array lookups (a.k.a. "dictionary style"), just as you mentioned in your question.
And that's the whole point. Some people like that, particularly people coming from languages that have it built in, like Python or PHP
The "this" keyword is an indexer
from http://msdn.microsoft.com/en-us/library/6x16t2tx.aspx
"Indexers allow instances of a class or struct to be indexed just like arrays. Indexers resemble properties except that their accessors take parameters."
You may have already stumbled across something similar before:
var myList = new List<string>();
myList.Add("One");
myList.Add("Two");
myList.Add("Three");
for(int i = 0; i < myList.Count; i++) {
string s = myList[i];
}
The indexer is the "primary key" of an object that implements a collection. It's just a shorthand way for writing a function like .GetValue(index) - syntactic sugar, if you want. But it also makes the intent clear.
It an implementation of the index operator [ ].
It's an operator overload. Useful if you are writing a collection class for example where it would make sense to access it using array notation, e.g. collection[someIndex].
You could of course write a collection.GetElement(someIndex) function equivalent, but it's a style/readability thing.
Well you could use this method in a key-value pair class.
I am not sure what the analogous class is in c#, but in c++ STL, there is the map class where you call the method with the SomeObject["key"] and it will return the "value" associated with that key.
That's called an Indexer, they allow you to use List<>, ArrayList, Dictionary<> and all the other collections using an array syntax.
It's just syntactic sugar, but it gives some readability when used right.
In my opinion, it's just a syntax convenience.
Where would you NOT use it:
public SomeClass {
private int[] nums;
public GetVal this[int ind] {
get {
return nums[ind]; // this is pointless since array is already indexed
}
}
}
Where would you benefit from it:
public Matrix {
private Dictionary<string, double> matrixData; // Matrix indecies, value
public double this[int row, int col] {
get {
return matrixData[string.Format("{0},{1}", row, col)];
}
}
}
As you can see, for some reason, your data is a Dictionary indexed with a string key and you wish to call this with two integer indecies and still do not want to change your data type:
Matrix m = new Matrix();
...
Console.WriteLine( m[1,2] );

Categories

Resources