Resharper with COM interop complains "Cannot access internal constructor" - c#

I have an OCX file built using VB6 that I'd like to access from C#. So I added a reference to the OCX in a C# project, and then added code to instantiate an object from the OCX:
var blah = new Blah();
This compiles just fine, without errors or warnings, and it seems to work as I would expect - I can call methods on the blah object and they seem to do what I would expect them to do. However, if I go to ReSharper / Inspect / Code Issues in Solution, ReSharper complains that the above quoted line is a "C# Compiler Error", saying "Cannot access internal constructor 'BlahClass' here".
Since it's claiming it's a C# compiler error, yet it seems to compile (and in fact work) just fine, I'm guessing it's just an issue with ReSharper itself. However, I'm pretty new to this, and I'd like to make sure. Perhaps what I'm doing is not the correct way of instantiating an object from an OCX, or something like that?
I am using VS2012 Professional and ReSharper 7.1.3.

The C# compiler looks at that coe and sees invocation of "dynamic" code (code whose objects may have new methods/properties available after execution started) and thus can't be sure that any particular method/property isn't there at compile time. Resharper tries to help out a bit more by trying to figure out circumstances that might fail at runtime. It may be using an out-dated description (type library) of that class to make its decision. Or, that description of that class is out of sync with what the code actually does. It's hard to tell solely based on what you've posted whether that's a good thing or a bad thing. If "it works", it seems like a good thing; but that's very subjective--it could be a problem waiting to happen.
I would see this as suspicious and maybe contact the vendor to get reassurance there isn't something lurking in there that will cause problems later.

Related

.NET: How do I mark a method as "Not yet used"?

I'm using ASP.NET and I know that I can mark a method as:
Obsolete
Not for future use
But I'm asking if I can mark a method as "Not yet used", that means "I wrote it but actually it is unused, sooner or later someone will using it".
Thanks!
You can throw a NotImplementedException with a appropriate message in your method. This will ensure during runtime that the method is not called.
public void MyMethod(){
throw new NotImplementedException("This will be implemented soon");
}
If you want to use metainformation you can define your own Attribute to decorate your methods. (But I think you can also reuse the ObsoleteAttribute with a special message)
No, you cannot. And it doesn't make much sense to do so.
Visual Studio 2015 does show you the method usage inside your current project, which is an indicator for 'dead' methods:
I assume you want it for a future functionality that currently is not active because is not fully implemented (is the only case I can imagine that make sense).
If you don't want it to be used don't put it in the interface (you should use interfaces) or put it in a distinct one that only you have. You can also use the Obsolete decorator with a "this is not meant to be used yet" message.
If anyone can use it because it's public and released you should not care about how many references it has. Usually you can't know it if the references are from outside your solution. You should not delete such a method because that is a breaking change.
If it's private your IDE should warn you and you can delete it or comment its future usage; add a reference to the functionality it is meant for so you can delete it in case it is closed (someone decides that is not going to be implemented).
This is managed by the NotImplementedException and can be very usefull when implementing interfaces where you know the members you need in the future but don´t want to implement them right now. Any user of the method will get the exception, however if you need a compile-time flag you´d be off by using the Obsolete-attribute together with a meaningul message such as "This method is not yet implemented" and the exception inside.
Just because you can doesn't mean you should....
Why write code that's not yet used?
That's like taking thermal underwear to the Sahara in case of a cold snap, when you're only visiting during the day.
While you can throw a NotImplementedException this won't give you compile time safety - it will just throw this exception on run time.
You can express all of your sorrow about the unused method in the Documentation Comment for this method. Just don't throw any NotImplementedException's or else this method isn't going to be used ever.
This is kinda dumb though, you should remove it if it is not used. As practice shows, most of the 'Not yet, but maybe some day' code is not going to ever be used at all, so it makes perfect sense to remove it. If for some reason you later need the method, you can always check your source control for that.
If you would like to litter your solution even more though, you can always do something stupid like implement your custom [PleaseUseMe]Attribute

Is it possible to instantiate and call a method of the class my Analyzer is analyzing right now?

My analyzer will match methods with certain signatures. I would like from inside my analyzer to create an instance of the class I'm analyzing and call the method that caused the analyzer to kick in.
Assuming the source code is in a compilable state, is it possible?
Getting the class name and method name is pretty easy, but Type.GetType(...) will always return null.
The purpose of this is that I would like for my analyzer to kick in when I'm on a test method and run it, failing if the test fails.
If the code is not ready for compilation, it would be fine to just return.
It seems possible, but you'd need to check the efficiency of these solutions. Also, you can't guarantee that the code is compilable.
You can grab the Compilation object (from let's say context.SemanticModel.Compilation), call Emit on it, and write it to disc. Then use Assembly.Load to load it, and then it's simple reflection to instantiate the class, whose name you already know, and call the method on it with appropriate arguments.
Another approach would be to use the Compilation in a scripting session as a reference assembly, and use the Roslyn Scripting API to invoke the method. There is a ToMetadataReference method on the Compilation, so you could get a MetadataReference, which could be then passed to ScriptOptions.Default.AddReferences. And then you'd need to pass the resulting options instance to CSharpScript.EvaluateAsync().
There's another fundamental reason you can't run code from the user's compilation, even if it did actually compile -- it might be the wrong environment. Consider a scenario where you're targeting Windows Phone, or Xamarin Android/iOS, .NET Core on Linux, or whatever. In any of these cases the compiler has reference assemblies that you can compile against but obviously you can't actually run that code because it's targeting a different platform. People often ask why you can't convert an ITypeSymbol to a reflection System.Type and back, and this is one of the reasons why -- the compiler can compile code on platform A for platform B, when it can't actually run (or fully load) B's assemblies in the first place.

Reverse of Deprecated / Obsolete

I have a functionality in my code, but it will be available from next version. Is there any tags to notify that it is not in use, but will be available in future. I just have one way ie, [Obsolete] with custom message. Expecting other than this.Thanks in advance.
If it is not available in the current version, don't make it part of the public API. Don't expose stuff that shouldn't be used by consumers of your library.
And even when it's not a library, don't add code that you don't yet need. That violates the YAGNI principle. Add the code only when it is actually needed.
You can create throw a CustomError message from that method saying "This method is not available for the current version. It is for future" something like that.
Or else you can make the method as Obselete and specify the reason in the message.
[Obsolete("I have written this method for future use. Do not use it in the current version.")]
Judging from your question, I assume you want to generate a compiler warning when someone attempts to call this method, stating that it has not yet been implemented.
ObsoleteAttribute is hard coded into the C# compiler as something that should generate a warning message. Therefore there is no way to mark a method as 'to be implemented in the future' without modifying the compiler itself.
From the C# Spec:
The attribute Obsolete is used to mark types and members of types that
should no longer be used.
If a program uses a type or member that is decorated with the Obsolete attribute, the compiler issues a warning or an error.
Specifically, the compiler issues a warning if no error parameter is
provided, or if the error parameter is provided and has the value
false. The compiler issues an error if the error parameter is
specified and has the value true.
I suggest to not expose methods that are not yet implemented, since it makes no sense to use them. If this is part of a team development effort, specifying API contracts before developing specific modules, you should consider throwing a NotImplementedException or provide a dummy implementation.
Reviving this question as there is now a real solution thanks to Roslyn: Code analyzers.
Just add this Nuget package to your project and you'll be able to create attributes that will be picked up by the compiler!
The GitHub repo readme has the instructions, and it's really simple.

Will the compiler only compile code that can get executed?

I have a class library and am using only part of it. Is there a need to delete what isn't being used in order to shrink the size of the created code (in release configuration)?
As far as I've seen, the compiler takes care of that, and removing the code doesn't change the EXE file size. Will this always be true? Removing all unneeded code would take very long, so I want to know if there's need for that.
More information: there are methods and classes in the class library that aren't called from the executing code, but are referenced by other parts of code in the class library (which themselves are never called).
No, the compiler includes the "dead" code as well. A simple reason for this is that it's not always possible to know exactly what code will and won't be executed. For example, even a private method that is never referenced could be called via reflection, and public methods could be referenced by external assemblies.
You can use a tool to help you find and remove unused methods (including ones only called by other unused methods). Try What tools and techniques do you use to find dead code? and Find unused code to get you started.
It all gets compiled. Regardless of whether it is called or not. The code may be called by an external library.
The only way to make the compiler ignore code is by using Compiler Preprocessor Directives. More about those here.
I doubt the compiler will remove anything. The fact is, the compiler can't tell what is used and what is not, as types can be instantiated and methods called by name, thanks to reflection.
Let's suppose there is a class library called Utility. You created a new project and added this class library to that project. Even if your EXE calls only 1-2 methods from the class library, it's never a good idea to delete the unreferenced code.
It would go against the principle of reusablity. Despite the fact that there would be some classes present in the library unreferenced from the EXE, it would not have any bad impact on performance or size of the program.
Determining all and only dead code is (if one makes the idealization that one has a "math world" like language) recursively undecidable, in most languages. (A few rare ones like the Blaise language are decidable.)
to the question of whether there is a "need to delete what isn't being used in order to shrink the size of the created code": i think this would only be useful to save network bandwidth. removing unused code is crucial in web applications to improve loading speeds etc.
if you're code is an exe or a library, the only reason i see to remove dead code, is to improve your code quality. so that someone looking at your code 2 years down the line won't scratch their heads wondering what it does.

Checking for the existence a reference/type at compile time in .NET

I've recently found the need to check at compile-time whether either: a) a certain assembly reference exists and can be successfully resolved, or b) a certain class (whose fully qualified name is known) is defined. These two situations are equivalent for my purposes, so being able to check for one of them would be good enough. Is there any way to do this in .NET/C#? Preprocessor directives initially struck me as something that might help, but it seems it doesn't have the necessary capability.
Of course, checking for the existence of a type at runtime can be done easily enough, but unfortunately that won't resolve my particular problem in this situation. (I need to be able to ignore the fact that a certain reference is missing and thus fall-back to another approach in code.)
Is there a reason you can't add a reference and then use a typeof expression on a type from the assembly to verify it's available?
var x = typeof(SomeTypeInSomeAssembly);
If the assembly containing SomeTypeInSomeAssembly is not referenced and available this will not compile.
It sounds like you want the compiler to ignore one branch of code, which is really only doable by hiding it behind an #if block. Would defining a compiler constant and using #if work for your purposes?
#if MyConstant
.... code here that uses the type ....
#else
.... workaround code ....
#endif
Another option would be to not depend on the other class at compile-time at all, and use reflection or the .NET 4.0 dynamic keyword to use it. If it'll be called repeatedly in a perf-critical scenario in .NET 3.5 or earlier, you could use DynamicMethod to build your code on first use instead of using reflection every time.
I seem to have found a solution here, albeit not precisely for what I was initially hoping.
My Solution:
What I ended up doing is creating a new build configuration and then defining a precompiler constant, which I used in code to determine whether to use the reference, or to fall back to the alternative (guaranteed to work) approach. It's not fully automatic, but it's relatively simple and seems quite elegant - good enough for my purposes.
Alternative:
If you wanted to fully automate this, it could be done using a pre-build command that runs a Batch script/small program to check the availabilty of a given reference on the machine and then updates a file containing precompiler constants. This however I considered more effort than it was worth, though it may have been more useful if I had multiple independent references that I need to resolve (check availability).

Categories

Resources