I have a C# assembly that uses "$(FrameworkSDKDir)\Bin\NETFX 4.0 Tools\tlbexp.exe" "$(OutDir)My.dll" /out:"$(TLBDir)My.tlb" so that I can call it from native components
I am looking at
.tlh generated on 2 machines is different and it appears to be a similar problem, but my difference is in visual2010 the tlh is generated using one case, and in 2012, it is generated using a different case.
Even more interesting this just happened a day ago. I have a build from the 18th that worked just fine, and the code has not changed in either solutions for many days.
Any thoughts before i continue down the /Names option?
I cannot easily tell you what to do to solve this problem, just highlight why this is happening. It doesn't have much to do with Tlbexp.exe, it is generic behavior implemented in the type library support built into Windows.
It has a tricky problem to solve, it cannot make any assumptions about the kind of language that was used to generate the types. The troublemakers are languages that are case-insensitive, Visual Basic being the prime example. Also the original language for which type libraries were invented. The issue is that it may emit names that can have different casing in different declarations but identify the same type. If the type library would use the same casing then it could only ever be consumed by a language-insensitive compiler.
So it does something about it, the algorithm it uses can at best be described as crude however. It looks at any name, regardless of what part of a declaration it is used, then forces the casing of any subsequent same name it encounters to the same casing. The usual big surprises are caused by names of function arguments. They can change the name of a function if it happens to match. So an "item" argument, pretty common, can spoil the name of an "Item" property. Or the other way around.
The wild-card here is order, I suppose that could be half an explanation.
Best way to address the problem is to change the name so there is no longer a collision. You have no trouble finding them, it is the one that changed casing. You may have to iterate a few times to find them all. Given that it is usually the name of an argument that causes this, feel free to change the argument name. Just put an underscore after it for example, it doesn't break binary compatibility nor the client code.
Related
The Assembly class has a GetReferencedAssemblies method that returns the
referenced assemblies. Is there a way to find what Types are referenced?
The CLR wont be able to tell you at runtime. You would have to do some serious static analysis of the source files - similar to the static analysis done by resharper or visual studio.
Static analysis is fairly major undertaking. You basically need a c# parser, a symbol table and plenty of time to work through all the cases that come up in abstract syntax trees.
Why can't the CLR tell you at run time? It is just in time compiled, this means that CLR bytcode is converted into machine code just before execution. Reflection only tells you stuff known statically at runtime about your types, and the CLR would only know if a type is referenced when the code is run. The CLR only knows when a type is loaded at execution time - at the point of just in time compilation.
Use System.Reflection.Assembly.GetTypes().
Types are not referenced separately from assemblies. If an assembly references another assembly, it automatically references (at least in the technical context) all the types within that assembly, as well. In order to get all the types defined (not referenced) in an assembly, you can use the Assembly.GetTypes method.
It may be possible, but sounds like a rather arduous task, to scan an assembly for which actual types it references (i.e. which types it actually invokes or otherwise mentions). This will probably involve working with IL. Something like this is best to be avoided.
Edit: Actually, when I think about it, this is not possible at all. Whatsoever. On a quite basic level. The thing is, types can be instantiated and referenced willy-nilly. It's not even uncommon for this to happen. Not to mention late binding. All this means trying to analyze an assembly for all the types it references is something like predicting the future.
Edit 2: Comments
While the question, as stated, isn't possible due to all sorts of dynamic references, it is possible greatly shrink all sorts of binary files using difference encoding. This basically allows you to get a file containing the differences between two binary files, which in the case of executables/libraries, tends to be vastly smaller than either of the actual files. Here are some applications that perform this operation. Note that bsdiff doesn't run on Windows, but there is a link to a port there, and you can find many more ports (including to .NET) with the aid of Google.
XDelta
bsdiff
If you'd look, you'll find many more such applications. One of the best parts is, they are totally self-contained and involve very little work on your part.
What determines the order of classes within an Assembly?
And.. is there a way to change it?
Additional info: you can check the ordering either through reflection yourself, or you can use a tool like ILDASM, disable the alphabetical sorting, and then you will also get the order.
Order seems to be in a strange way determined by the compiler.
I already tried some things.. like renaming the classes (order stays the same), also editing the .csproj file to change the order of the .cs files.
My main focus is VS2008, C#, .net 3.5.
Update: I do have a scenario where the order matters (external program going through my assembly through reflection) - and I need special order there.
Apart from this - you are totally right - order really should not matter.
I'm going to stick my neck out here and say this is an implementation detail and may well be decided by any particular compiler.
Since this is an implementation detail you shouldn't or needn't be concerned. Of course if this really is important (can't see why) you can always write your own IL.
I leave you with the following quote from Eric's blog:
Is compiling the same C# program twice guaranteed to produce the same
binary output?
No.
What determines the order of classes within an Assembly?
The compiler.
And.. is there a way to change it?
Write your own IL directly.
That being said, the order of the types within the assembly really doesn't matter. You can use the types with no regard to their order.
A similar question has been asked in Ordering of reflection requests in dotnet
But I'm hoping for a different answer... I'm writing a plugin for a program that uses reflection to interrogate plugins to find the entry point. Unfortunately it has a bug which means if it encounters an interface declaration during this process it crashes with an unhandled exception. I have spoken to the development team and this is unlikely to be fixed. This is extremely limiting for me for obvious reasons. One workaround I have already thought of is to have my assembly load another assembly with the interfaces in it, but for reasons I won't go into this is not a great solution. It was a while before I encountered this problem because for some reason my entry class always preceded my interfaces in the reflection enumeration order.
My question is, is there any way to influence the ordering of classes and interfaces in the assembly?
Note: I have already tried setting different accessibility levels on my interfaces but that doesn't work for me.
Cheers,
J
I'd bet the code using AppDomain.GetAssemblies() which are then inspected. The implementation of AppDomain.GetAssemblies() leads to an external method, so Reflector is of mostly no help here.
However, without actually trying it and inspecting the result, there are two logical options for the ordering of assemblies in the result:
Load order
Alphabetical order
In the first case you'd probably have to organize references among your assemblies and the load order in such a way that the foreign code finds the right assembly with the entrypoint class and stops. In the second case it would be a pure matter of naming the assemblies in a 'right' way but I doubt it's this case.
(However, the order may be completely different from the two above, e.g. 'mostly' random as well.)
In either case I think sooner or later the buggy code will encounter the problematic assembly and crash anyway. Thus the strong recommendation is: insist on having the bug fixed.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
The community reviewed whether to reopen this question 1 year ago and left it closed:
Original close reason(s) were not resolved
Improve this question
I want to be able to distinguish between a generic and regular (non-generic) version of a class. Much like the .NET framework does with it's generic and non-generic versions of several of it's interfaces and collection classes. (Queue, Queue(T))
I generally like to follow the convention of one class per file (as in Java). Is there a common convention for naming files containing a single generic class? I'm mostly interested in Windows (NTFS specifically) but it seems like a good convention would be (at least a little) portable.
At Microsoft, they use ClassNameOfT.cs.
Just found this question after looking for what conventions other people use for generic class filenames.
Lately I've been using ClassName[T].cs. I really like this convention, and I think it's superior to the others for the following reasons:
The type parameters jump out at you a
little more than they do with the
Microsoft convention (e.g.,
ClassNameOfT.cs).
It allows you to have multiple
type parameters without too much
confusion: Dictionary[TKey,
TValue].cs
It doesn't require you to create any special folders, or to have your generic classes in a special namespace. If you only have a few generic classes, having a special namespace dedicated to them just isn't practical.
I borrowed this convention from Boo's generic syntax, albeit slightly modified (Boo uses ClassName[of T]).
Some developers seem to have a phobia of filenames that contain anything but letters and underscores, but once you can get past that this convention seems to work extremely well.
I see that this topic has been abandoned more than a year ago, but still I would like to share my view on this convention.
First of all, having multiple classes that have the same name but only differ in the amount of type-parameters isn't always a case of backwards compatibility. Surely, you don't see it very often, but the new Action- and Func-classes of .NET were just designed this way, and I'm currently implementing something similar.
For clarity and distinguishability, I use the following convention that only specifies the number of generic arguments for a given type:
MyClass.cs
MyClass.T1.cs
MyClass.T2.cs
This way, my filenames stay short and simple while still clearly communicating the class-name and the different amount of type parameters at the cost of a simple extra dot (which is, in my experience, a commonly accepted thing to do in a filename and looks much better than comma's and other non-alpanumeric characters, but this is just a matter of taste I guess). Putting the names (or acronyms) of the type parameters just lengthens the filenames while at this level I'm not really interested in the actual names of the type parameters anyway...
Don't use the grave accent ` in your generic file names if you're running Visual Studio 2008. There's a known issue with them that causes breakpoints to fail:
http://connect.microsoft.com/VisualStudio/feedback/details/343042/grave-accent-in-filename-causes-failure-to-recognize-target-language-breakpoints-fail
Personally I wouldn't use the grave accent notation:
Foo.cs
Foo`1.cs
For the simple reason that I am scared of the grave accent. Not only does it have a scary name 👻😨😱, but I am unsure how it will be handled by different file systems, version control systems and in URLs. Hence, I would prefer to stick to common alphanumeric characters.
NameOfT.cs seems to be used in ASP.NET Core according to a search on GitHub. 40 results. Reference.
Also used in the .NET Core runtime. 36 results. Reference.
Example:
Foo.cs
FooOfT.cs
Sometimes I also see ClassName{T}.cs but it is common to name it ClassNameOfT.cs (like mentioned before Microsoft uses it)
EntityFrameworkCore project(also Microsoft's) uses ClassName`.cs
All new Microsoft classes use generics. The Queue and ArrayList were there before generics came out. Generics is the way forward.
The convention for one-class-per-single file is to name the filename after the class name (whether generic of not). For MyClass, you'll have MyClas.cs. For every new namespace you'll need to create a new folder. This is how Visual Studio also works.
How about:
Type.cs
and
TypeGeneric.cs
Whenever I have done this in the past I have always put both types in one file with the non-generic type as the file name. I think that this makes things pretty clear as .NET has no conventions/restrictions on one type per file like Java does.
But if you must then I would suggest something like I have above, and using a suffix will make the files show up together in any alphabetized list (Solution Explorer, Windows Explorer, etc.).
Here is another idea:
Type`1.cs
This would allow you to break out different generic types by the number of generic type parameters they accepted. Its just a thought though as I still think it would be simpler to just put all the types in one file.
I would probably put them in folders and use the namespace mechanism instead. You can compare with System.Collections vs. System.Collections.Generic. On the other hand, if it's more common than not that the classes use generics, perhaps it's better to point out those that are not. That is if you really want to separate the generic classes from other classes. Personally I usually don't bother to do that, since I don't really see a practical benefit from it.
From the responses so far it seems there isn't a consensus.
Using the same filename in a sub-namespace (and sub-folder) "Generics" (like System.Collecctions.Generics) is an option. But it's not always desirable to create a new namespace.
For example, in an existing namespace with non-generic classes that are maintained for backwards compatibility, but marked with ObsoleteAttribute, it's probably better to keep the generic versions in the same namespace.
I think a suffix is a reasonable way to go. I've adopted a convention of using the type parameters as a suffix (so: MyClassT for MyClass<T>, or MyDictionaryKV for MyDictionary<K,V>.
I'd probably have two folders in the project, something like Gereric, NonGeneric or something like that. They can still be in the same namespace, and then they can both have the same file name. Just a thought...
In a recent VB.NET project I adopted the naming conventions I'm used to using in C#. Namely, often calling a variable the same name as the class it references, only with a different case, e.g.
Foo foo = new Foo(); // C#
Dim foo As New Foo() ' VB.NET
I find this is often the clearest way to write code, especially for small methods. This coding style obviously works fine in C#, being case sensitive, and because of the syntax highlighting provided by Visual Studio, it is very easy to see that the class name and the variable name are different.
However, to my surprise, this also worked fine nearly 100% of the time* in VB.NET. The only issue was that the variable name then appeared to take on a multiple identity. Namely it could be used to call both instance methods and Shared (static) methods of the Foo class. This didn't really cause any problems though, it just meant that Intellisense would provide a list containing both static and instance methods after you hit the '.' after the variable name.
I found, again to my surprise, that this didn't actually lead to any confusion in my project, and it's been very successful so far! However I was the only person working on this particular project.
Here is a slightly longer example:
Dim collection as Collection = New Collection()
For Each bar As Bar in Bar.All()
collection.SomeInstanceMethod(bar)
Next
collection.SomeSharedMethod()
* The only issue I found with this was that sometimes the 'Rename' refactoring tool got confused, i.e. when renaming a class it would rename the variables with the same name as the class as well, in their declaration lines (Dim foo As...), but not the other references to that variable, causing compiler issues (duh). These were always easy to correct though.
Another small annoyance is that the VB.NET syntax highlighter doesn't highlight class names any differently than variable names, making it not quite as nice as when using it in C#. I still found the code very readable though.
Has anyone else tried allowing this in a team environment? Are there any other potential issues with this naming convention in VB.NET?
Although VB is case-insensitive, the compiler is intelligent enough to not being confused between the object-instance and the class.
However, it's certainly very dangerous and wrong to use the same name in a case-insensitive language! Especially if other programmers are working on that project.
I have to move back and forth between VB and C#, and we consider this poor practice. We also don't like letting variable names in C# differ from their type only by case. Instead, we use an _ prefix or give it a more meaningful name.
Whenever you start a new language it's inevitable you'll notice a bunch of things that are different and miss the old way of doing things. Often this is because you are initially unaware of different features in the other language has that address the same problem. Since you're new to VB, here are a couple notes that will help you get things done:
It's not 100% correct to say that VB.Net is case-insensitive unless you also make the point that it is case-aware. When you declare an variableidentifier, the IDE will take note of what case you used and auto-correct other uses to match that case. You can use this feature to help spot typos or places where the IDE might be confused about a variable or type. I've actually come to prefer this to real case-sensitive schemes.
VB.Net imports namespaces differently. If you want to use the File class, you can just say IO.File without needing to import System.IO at the top. The feature especially comes in handy when learning a new API with a few nested namespace layers, because you can import a top-level section of API, type the next namespace name, and you'll be prompted with a list of classes in that namespace. It's hard to explain here, but if you look for it and start using it, you'll really miss it when going back to C#. The main thing is that, for me at least, it really breaks my flow to need to jump to the top of the file to add yet another using directive for a namespace I may only use once or twice. In VB, that interruption is much less common.
VB.Net does background compilation. The moment your cursor leaves a line, you know whether or not that line compiles. This somewhat makes up for not highlighting class names, because part of why that's useful in C# is so you know that you typed it correctly. VB.Net gives you even more confidence in this regard.
I'm going to differ with the rest of the answers here... I don't think there is any problem with doing this. I do it regularly, and have absolutely 0 problems resulting from it.
If you use lowercase for the variable name you can easily differentiate the variable from the type, and the compiler will not confuse the two identifiers.
If you delete the variable declaration, the compiler will think other references to this variable now refer to the type, but it's not really a problem because those will be tagged as errors.
I have done the same thing in the past. I'm starting to move away from it though because Visual Studio will occasionally get confused when it auto formats the code and changes the casing on my static method calls to lower case. That is even more annoying than not being able to differentiate the variable and class names by case only. But, purely from technical perspective it should not cause any issues.
As Moayad notes, the compiler can tell the difference--but it's bad practice that can lead to maintenance issues and other side effects.
A better practice all-around is to try to name the variable in the context they're being used, rather than just the type name. This leads to self-documenting code and requires fewer comments (comments are greatly abused as an excuse to write dense code).
It's only safe as long as the compiler can always tell whether Foo means the class or the variable, and eventually you'll hit a case where it can't. Eric Lippert discusses the sort of thing that can go wrong on his blog.
I use this convention all the time, and it's never been a problem. The most natural name for a variable is often the class name, and therefore that's what you should call it (Best name for an arbitrary Line? line.).
The only downside is when some tool interprets the context incorrectly. For example, visual studio 2010 beta 1 sometimes uses the class highlight on variables named the same as the class. That's a bit annoying.
Context sensitivity is much closer to how I think than case sensitivity.
Well, this isn't the final answer, and I don't think there is a definitive one, but the general opinion seems to be that it's not a good idea to use this naming convention! There must be one true way to write nice VB.NET variable names though, and I don't like any of the alternatives...
Here are links to the official Microsoft guidelines for anyone who's interested, although they don't seem to cover this particular question (please correct me if I've missed it).
Visual Basic Naming Conventions: http://msdn.microsoft.com/en-us/library/0b283bse.aspx
Declared Element Names: http://msdn.microsoft.com/en-us/library/81ed9a62.aspx
Cheers all!
VB.NET isn't case sensitive! This equates to:
Foo Foo = new Foo(); // C#
As a standard in our team environment we would use:
Dim oFoo as New Foo 'VB.NET