How to hide Non-CLS compliant code from projects using other languages? - c#

This question is more out of curiosity than a project requirement or a problem.
I have a Non-CLS compliant code in one language (say C#), and I need to use it like that only in my current language (across projects, so making internal is not a choice), and at the same time want to allow other languages (say VB) to be able to call the conflicting implementations without generating compile time error.
For instance,
//C#
public class SecurityService
{
....
public void Print()
{
Console.WriteLine("print"); //This method prints Service Name in lower case
}
public void PRINT()
{
Console.WriteLine("PRINT");//This method prints service name in UPPER case.
}
}
'VB.Net
Module ServiceReader
Sub Main()
Dim service As New SecurityService()
service.print() 'Compile time error: print is ambiguos
End Sub
End Module
Problem: I need to avoid the compile time error here by somehow hiding one of my 'print' methods from cross language projects (allowing C# projects to call the desired implementation).
Thanks for your interest.

A language like VB.NET offers no escape around its fundamental syntax rule that identifiers are case insensitive. It is not hard to solve, you can simply write a little static adapter method in a case sensitive language like C# that makes the call.
public static class Interop {
public static void Print2(SecurityService obj) {
obj.PRINT();
}
}
You can completely shove it under the doormat by making it an extension method, assuming the language supports it. There will be no actual runtime overhead when the jit optimizer is done with it.

I'd suggest you make the non-CLS compliant methods/properties internal, but then make another class that isn't CLS compliant to call that stuff and mark that class as [CLSCompliant(false)]

I don't see the point of trying to make this work. My advice would be to avoid the problem in the first place and stop writing non-compliant code, especially if you are planning on supporting different languages. You have total control over the module here so you shouldn't actually need any fancy hacks.

Related

Can I Split my C# local method across multiple files?

I have this:
(note: this is not the main file, that's why it doesn't have the Main method)
namespace MJeC_Sharp
{
class Program
{
public static void Game()
{
Move();
void Move()
{
}
}
}
}
Is there a way to have void Move() on another file while keeping the conveniences of not having to pass variables to it?
No, local methods have to be written inside the text of their outer method and there is no way to split a single method into multiple files.
It is possible to split the same class into multiple files - so a non-local method can be easily written in a separate file - Can I split my C# class across multiple files?.
Note that in C/C++ you can do something like that by using pre-processor's #include statement - C# does not support that, but if you really need such functionality and your team is comfortable with modifying build you can try using C preprocessor to do includes before compiling code with C#. Note that the source code will no longer pass C# syntax checks (as included methods will be missing) - so it probably not useful for human readable code (maybe useful in some code gen cases ).

Define own keywords and meanings

Is it possible to define your keywords in C#?
I mean something like
public important Form newform;
where important would be the new keyword. It would mean something like, for example, that if the type is null when compiling an error occurrs. So the example would produce an error. An example with no error would be
public important Form newform = form1;
No, the compiler doesn't allow you to add keywords out of box.
That doesn't mean you can't accomplish what you want, but it's going to be non trivial. You're going to need to perform your own custom static code analysis.
Roslyn
One way to do it is via the new .NET Compiler Services (Roslyn) Code Analyzers. You can read this MSDN article to get started: https://msdn.microsoft.com/en-us/magazine/dn879356.aspx and you'll end up with something that looks like this:
This will work from within Visual Studio, and you can generate at least Warnings, I would assume Errors as well (or you'll have to turn on "Treat Warnings as Errors").
Because you want to declaritively add the check to certain variables, you'll need to make use of Attributes:
/// <summary> Indicate a variable must be given a value
/// in the same line it's declared </summary>
public class ImportantAttribute : Attribute {}
public class Program
{
[Important]
object thisShouldError;
object thisIsFine;
}
Then when you write your Analyzer you'll need to check the variable declaration node to see if it's decorated with Important.
If you want this to work on a build server (or outside of VS), you might need to do some more work: Roslyn: workspace loads in console application but not in msbuild task
StyleCop
The easiest way is probably to use Code Analysis (ie StyleCop) to run Static Analysis Rule Sets against your code base:
You'll need to write your own Rule Set and I don't know if the Rule Sets will give you fidelity to be able to declare which variable declarations you want to force a check on, ie I don't know if you'll be able to mix & match this:
public class Program
{
[Important]
object thisShouldError;
object thisIsFine;
}
Fody
Another approach is to use an IL weaving tool like Fody that lets you manipulate the IL of your application during compilation. AFAIK you can't directly generate compilation errors, but you might be able to add invalid IL that will in turn generate a compile time error.
So based on the same code as above, after a compilation pass with Fody you'd end up with code like:
public class Program
{
[Important]
object thisShouldError YouForgotToInitializeThisImportantVariable;
object thisIsFine;
}
Custom Compiler
Microsoft did open source the C# compiler: https://github.com/dotnet/roslyn. So if you're feeling really ambitious, you can absolutely add in your own keywords in your own fork of the compiler. Of course then you'll essentially have your own language and it won't be able to compile on anything other than your custom compiler.
Short: No you can't.
Long: It is possible, but it it's probably never happening, as you would require for the C# team to add it, but that would require a lot of discussion and a lot of feasible uses for it.
Maybe you can simply use tools like ReSharper... To define new keyword only for finding uninitialized public variables sounds as bad idea.
No, you cannot create a new keyword in the way you have indicated. I suggest you take a look at this.
Create new keyword for C# automatic property

Removing preprocessor branching in C#

I am refactoring some source code and got a task to remove preprocessor compiling. I have now searched internet for some days, but haven't found any good idea how to do that. I am also quite new to C#.
So the problem is following, I have different interfaces (classes) for every device and "ControlLogic" class needs to use only one of them at the time. Device is chosen on program run-time.
So far "device" variable (also used globally) is used in a lot of places and considering renaming that doesn't make sense to me. Also all device interfaces (classes) are derived from base class, but interface classes does implement different methods for them.
public class ControlLogic
{
#if FIRST_DEVICE
public FirstDeviceInterace device = null;
#elif SECOND_DEVICE
public SecondDeviceInterface device = null;
#elif THIRD_DEVICE
public ThirdDeviceInterface device = null;
#endif
// One example method
public void startDevice()
{
if (device != null)
{
#if (FIRST_DEVICE || SECOND_DEVICE)
device.startDevice();
#endif
#if THIRD_DEVICE
device.startThirdDevice();
#endif
}
}
// More code.....
}
So what is the best way to remove preprocessor compiling?
I've faced with a similar task a few months ago: large C# code base and extensive preprocessor directives usage. Manual refactoring looked like a long boring monkey job there.
I've failed with unifdef, sunifdef and coan C tools because of C# syntax specifics like #region and some others. In the long run I've made my own tool undefine. It uses regexp to parse the preprocessor directives and sympy python library to simplify logical expression. It works good for me on large 10M lines code base.
I understand that the three device types do not have a common base class or interface. You cannot just pick one of the three at runtime and type all variables with a base type.
Here are a few options:
Find a way to a a common base type.
If you cannot modify the classes (or it would be inappropriate for some reason) write a wrapper. That wrapper can have any structure you like. You could have one wrapper per device class with a common base type.
Use dynamic. This can be a quick fix at the cost of less tooling help (less autocompletion, less documentation at hand, less quick static error checking).
Using #if to solve this problem is very unusual. It is problematic because the amount of testing to even make sure the code compiles has now tripled. You also need multiple binaries.

What's the C# equivalent of perl warn?

In Perl I can say
use warnings;
warn "Non-fatal error condition, printed to stderr.";
What is the equivalent of this in C# ASP.NET? Specifically what I'm looking for is something so that other members of my team can know when they're still using a deprecated routine. It should show up at run time when the code path is actually hit, not at compile time (otherwise they'd get warnings about code sitting at a compatibility layer which ought to never run anyway.)
My best option so far is to use Trace, which feels like a bad hack.
Use ObsoleteAttribute. Decorate it over any method you want to mark as deprecated. They'll get a warning in their errors window, but the app will still compile.
public class Thing
{
[Obsolete]
public void OldMethod() { Console.WriteLine("I'm Old"); }
}
EDIT: I hadn't seen the bit in the question saying you wanted it at execution time.
The problem about writing out data execution time is that you need to know where to write it. What logging does your application use in general? Use the same form of logging as that, basically.
I would still favour the compile-time option listed below, however - you can turn off specific warnings in the compatibility layer using #pragma warn disable/restore, but it'll make it a lot easier to spot the problems than hoping someone reads a log file...
Old answer
Use the [Obsolete] attribute on any type or member. You can decide whether this should end up being a warning or an error. For example:
using System;
class Test
{
static void Main()
{
OldMethod();
BadMethod();
}
[Obsolete("Use something else instead")]
static void OldMethod() {}
[Obsolete("This would destroy your machine!", true)]
static void BadMethod() {}
}
Compiling this gives:
Test.cs(7,9): warning CS0618:
'Test.OldMethod()' is obsolete: 'Use
something else instead'
Test.cs(8,9):
error CS0619: 'Test.BadMethod()' is
obsolete: 'This would destroy your
machine!'
Ideally, the message should explain what the effects of continuing to use the method would be, and the suggested alternative.
You can use Trace.TraceWarning for run-time obsolete method usage detection, BUT you should really rethink your design and use ObsoleteAttribute and compile-time detection.
Run-time detection of such errors should be the last resort.
If your compatibility layer is auto-generated code, you can check for ObsoleteAttribute when generating the shims and mark such shims also [Obsolete]
If your compatibility layer uses reflection, it can check for ObsoleteAttribute and emit the warnings.
If your compatiblity layer is hand-coded you can write a tool that automatically inspects the IL in your compatibility layer and marks compatibility-layer methods [Obsolete] based on which methods they call.
In each case it would be best if all obsolete methods were actually marked with [Obsolete] so new code will not call them.
If your compatibility layer includes shims that call obsolete methods and these are also marked [Obsolete] you can safely compile it using this:
#pragma warning disable 618
This will hide the obsolete warnings when compiling the compatibility layer. Since your compatibility layer methods are also marked [Obsolete] you will get warnings at the correct locations.
FYI there is a #warning directive that can be used for run time warning generation; however, the [Obsolete] attribute sound much more like what you need.
There is no equivalent to warn's __WARN__ handling, but the printing to STDERR can be accomplished with a simple Console.Error.WriteLine() call.
That said, what you're really trying to do is mark something obsolete or deprecated, and others have shown you how to do that. Use that method rather than inserting warn calls into your function.
I think the Trace class is your best bet. Depending on how you intrusive you want to be you can use different trace levels or even a Fail statement (which brings up the nasty assert dialog).
private void SomeOldMethod()
{
Trace.Fail("You shouldn't call this method"); // <-- this will bring up an assert dialog
Trace.TraceWarning("You shouldn't call this method");
Trace.TraceError("You shouldn't call this method");
}
the way to flag a method as deprecated in c# is to use the obsolete attribute, this is overloaded to take a message to output (on intellisense) and a bool as to whether it should allow compile or not. I am not 100% convinced this matches what you want though, I am unfamiliar with perl
[Obsolete("A message",false)]

Using Extensions: Weighing The Pros vs Cons

Recently I asked a question about how to clean up what I considered ugly code. One recommendation was to create an Extension Method that would perform the desired function and return back what I wanted. My first thought was 'Great! How cool are Extensions...' but after a little more thinking I am starting to have second thoughts about using Extensions...
My main concern is that it seems like Extensions are a custom 'shortcut' that can make it hard for other developers to follow. I understand using an Extension can help make the code syntax easier to read, but what about following the voice behind the curtain?
Take for example my previous questions code snippet:
if (entry.Properties["something"].Value != null)
attribs.something = entry.Properties["something"].Value.ToString();
Now replace it with an Extension:
public static class ObjectExtensions
{
public static string NullSafeToString(this object obj)
{
return obj != null ? obj.ToString() : String.Empty;
}
}
and call using the syntax:
attribs.something = entry.Properties["something"].Value.NullSafeToString();
Definetely a handy way to go, but is it really worth the overhead of another class object? And what happens if someone wants to reuse my code snippet but doesn't understand Extension? I could have just as easily used the syntax with the same result:
attribs.something = (entry.Properties["something"].Value ?? string.Empty).ToString()
So I did a little digging and found a couple of articles that talked about the pros/cons of using Extensions. For those inclined have a look at the following links:
MSDN: Extension Methods
Extension Methods Best Practice
Extension Methods
I can't really decide which is the better way to go. Custom Extensions that do what I want them to do or more displayed code to accomplish the same task? I would be really interested in learning what 'real' developers think about this topic...
Personally I think the "problems" of extension method readability are vastly overstated. If you concentrate on making your code easy to read in terms of what it's doing, that's more important most of the time than how it's doing it. If the developer wants to trace through and find out what's actually happening behind the scenes, they can always click through to the implementation.
My main problem with extension methods is their discovery method - i.e. via a specified namespace instead of a specified class. That's a different matter though :)
I'm not suggesting that you put in extension methods arbitrarily, but I would seriously consider how often you need to know how every expression in a method works vs skimming through it to see what it does in broader terms.
EDIT: Your use of terminology may be misleading you slightly. There's no such thing as an "extension object" - there are only "extension methods" and they have to exist in static types. So you may need to introduce a new type but you're not creating any more objects.
[OP] Definetely a handy way to go, but is it really worth the overhead of another class object?
No extra class object is created in this scenario. Under the hood, extension methods are called no differently than a static method. There is an extra metadata entry for the extension method container but that is pretty minimal.
[OP] And what happens if someone wants to reuse my code snippet but doesn't understand Extension Objects?
Then it would be a good time to educate them :). Yes, there is the risk that a new developer may not be comfortable with extension methods to start. But this is hardly an isolated feature. It's being used more and more in all of the code samples I'm seeing internally and on the web. It's something that is definitely worth while for a developer to learn. I don't think it fits into the category of "to esoteric to expect people to know"
The only serious weirdness to deal with in Extension methods are:
They do not have to cause a null reference exception if the left hand side (the object on which it appears you are invoking a method) is null.
can sometimes be useful, but is contrary to expectations as such should be used with extreme caution.
They are not accessible through reflection on the classes/interfaces to which they apply.
generally not a problem, but worth keeping in mind.
Name collisions with other extension methods involve a lengthy resolution rule sequence
if you care the sequence is to prefer:
Extension methods defined inside the current module.
Extension methods defined inside data types in the current namespace or any one of its parents, with child namespaces having higher precedence than parent namespaces.
Extension methods defined inside any type imports in the current file.
Extension methods defined inside any namespace imports in the current file.
Extension methods defined inside any project-level type imports.
Extension methods defined inside any project-level namespace imports.
[OP] And what happens if someone wants to reuse my code snippet but doesn't understand Extension Objects?
The extension methods will not show in the intellisense for the object if the assembly that implements them is not references in the project. Your code snippet will also not compile. That could potentially create a bit of a confusion to the other developer.
If the extension method assembly is referenced, it will show in the intellisense, but it will be not mentioned in the documentation for the object. This could potentially cause a bit of confusion as well.
However, as #JaredPar mentioned, the extension methods as a technique are used more and more and I would expect most of the C# programmers to know about them. Thus, I wound't be too worried about any potential confusion.
C# Extensions is an additional "tool" provided by .Net in order to help you write your code a little bit nicer. Another advantage of them is, that they handle null. Although they seem very usable, I try to use them only in certain cases that will really tidy up my code, because they are not standard coding methods and they stand a little bit seperate from other classes as they have to be in static classes and are static themselves.
Let's say their implementation is a little bit untidy, but their use is made tidier.
It is also important to mention that they only exist in C# and VB.Net (Java doesn't have Extensions). Another important fact is that Extensions have no priority over standard methods, meaning that if a method is implemented in a class with the same name as an extension method on the same class, then the first method is the one that will be called and not the extension method.
Below there are three cases where I often use them, why I use them and alternative solutions that would solve the same problem:
1. To implement specific methods for generic classes:
I have a generic type, let's say a collection List<T>. I want to do a method that applies only to a specific kind of list. Let's say a method that creates a union from a list of strings using a seperator
("A", "B", "C", " sep " --> "A sep B sep C"):
public static string union(this List<string> stringList, String seperator)
{
String unionString = "";
foreach (string stringItem in stringList) {
unionString += seperator + stringItem; }
if (unionString != "") {
unionString = unionString.Substring(seperator.Length); }
return unionString;
}
In case I didn't want to use an extension, I would have to create a new class "StringCollection : List<string>" and implement my method there. This is mainly not a problem and it is actually better in most cases, but not in all cases. If for example you are receiving all your data in lists of strings in many cases, you don't have to convert those lists in StringCollections each time you want to use union, but use an extension instead.
2. To implement methods that need to handle null:
I need a method to convert an object to a string without throwing an exception in case the object is null
public static String toStringNullAllowed(this Object inputObject)
{
if (inputObject == null) { return null; }
return inputObject.ToString();
}
In case I didn't want to use an extension, I would have to create a class (probably static), for example StringConverter, which will do the same job, with more words than a simple myObject.toStringNullAllowed();
3. To extend value types or sealed classes:
Value types such as int, float, string, etc as well as sealed classes (classes that cannot be inherited) cannot be extended through inheritance. Below you can see an example of extending integers to be able to be converted to x-digit Strings (for example integer 34, digits 5 --> "00034"):
public static String toXDigit(this int inputInteger, int x)
{
String xDigitNumber = inputInteger.ToString();
while (xDigitNumber.Length < x) { xDigitNumber = "0" + xDigitNumber; }
return xDigitNumber;
}
Again an alternative solution would be a static class (like a toolbox), let's say "Math".
In that case you would write: Math.toXDigit(a, x);
While with the extension method: a.toXDigit(x);
The extension method looks better and is more understandable, like speaking English
To conclude, I guess the disadvantage of extensions is that their implementation is seperated from standard classes and looks a little bit odd or difficult to programmers that are not used to them, while their advantage is that they offer a more understandable, tidier and encapsulated use of the language.

Categories