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.
Related
First, yes, I have seen these posts:
Is there an easy way in C# to have conditional compilation symbols based on OS version
Conditional compilation depending on the framework version in C#
but they do not target the direction I am looking for.
What I am looking for specifically is variable _type_ qualification via OS version:
public struct REPASTESPECIAL
{
UInt32 dwAspect;
#if WINVER >= 6.0
UIntPtr dwParam;
#else
UInt32 dwParam;
#endif
}
I do not wish to revert to something like this:
public struct REPASTESPECIAL<T>
{
UInt32 dwAspect;
T dwParam;
}
// return type by OS version
public static Type GetRePasteSpecial_ParamType()
{
if (Environment.OSVersion.Version.Major >= 5) return typeof(IntPtr);
else return typeof(UInt32);
}
...as that would permit programmers to use any object of Type T when I desire dwParam to be an IntPtr or an UInt32 object only, but if I must then so be it, and make this a reference for others looking for the same.
No - conditional compilation works at compile time, whereas it looks like you're after something which works at execution time.
EDIT: Just thinking about it, you could use conditional compilation in one sense: you could encapsulate this as far as possible in its own assembly, and compile it two ways, producing two separate assemblies. Then at install time (or whatever) install the right assembly. It's hard to know how feasible that is without knowing what kind of app you're writing though.
Answer to: "I have some ugly logic that I'm afraid will be misused when I expose it to others"
Consider exposing nice and usable API which does not let any misuse. Declare all interop types as inner classes and structures of implementation f you nice API, there is not much value to make innermost classes like REPASTESPECIAL to be publicly visible/usable.
This way you can hide ugly class/struct types and dynamically pick OS specific implementation if needed.
If this educational project - than it would be good place to learn about dependency injection to configure correct implementation at run-time.
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.
How to easily/quickly replace float's for doubles (for example) for compiling to two different targets using these two particular choices of primitive types?
Discussion:
I have a large amount of c# code under development that I need to compile to alternatively use float, double or decimals depending on the use case of the target assembly.
Using something like “class MYNumber : Double” so that it is only necessary to change one line of code does not work as Double is sealed, and obviously there is no #define in C#.
Peppering the code with #if #else statements is also not an option, there is just too much supporting Math operators/related code using these particular primitive types.
I am at a loss on how to do this apparently simple task, thanks!
Edit: Just a quick comment in relation to boxing mentioned in Kyles reply: Unfortunately I need to avoid boxing, mainly since float's are being chosen when maximum speed is required, and decimals when maximum accuracy is the priority (and taking the 20x+ performance hit is acceptable). Boxing would probably rules out decimals as a valid choice and defeat the purpose somewhat.
Edit2: For reference, those suggesting generics as a possible answer to this question note that there are many issues which count generics out (at least for our needs). For an overview and further references see Using generics for calculations
The best way to do this would be using #if as Andrew stated above. However, an interesting idea to think about would be something like this:
#if USE_FLOAT
using Numeric = System.Single;
#endif
#if USE_DOUBLE
using Numeric = System.Double;
#endif
#if USE_DECIMAL
using Numeric = System.Decimal;
#endif
public class SomeClass
{
public Numeric MyValue{get;set;}
}
EDIT:
I still really like this solution, it allows you to do some other really cool things such as:
Numeric.Parse();
Numeric.TryParse();
Which will work for all three types
At worst I think you could use boxing and something like this:
#if USE_FLOAT
public float OutputValue(object input)
{
return (float)input;
}
#endif
#if USE_DOUBLE
public double OutputValue(object input)
{
return (double)input;
}
#endif
and call OutputValue(1.5); to get it to convert it for you.
One approach would be to have a generic around the base type you need. Then you declare a class that inherits specific instance of that generic in a separate .cs file and you create three copies of this class for each base type you need. Then you change your .csproj to include the proper .cs file based on the build configuration.
Note that I have not really tried this, so there might be couple of kinks to iron out.
You could do this:
public struct NumberContainer<T>
{
T _number;
// accessor, and possibly: operators, cast methods, etc.
}
And then:
#if USE_FLOAT
public struct MyNumber : NumberContainer<float>
#else
public struct MyNumber : NumberContainer<double>
#endif
{
}
This is difficult, since the basic types do not impelment something like IArithmetic. This has been suggested many times on Connect. Unfortunately, this is a well known limitation of generics.
There are some workarounds, using a "calculator" struct class. If the math isn't too onerous that's being done, this works very, very well.
However, it's clunky. This is one place where generics are not as flexible as C++ templates.
One other approach could be to use something like the Text Template Transformation Toolkit (T4) to generate a template that would work with any type, and compile separate ones per type.
I went through all the posts on reflection but couldn't find the answer to my question.
What were the problems in the programming world before .NET reflection
came and how it solved those problems?
Please explain with an example.
It should be stated that .NET reflection isn't revolutionary - the concepts have been around in other framework.
Reflection in .NET has 2 facets:
Investigating type information
Without some kind of reflection / introspection API, it becomes very hard to perform things like serialization. Rather than having this provided at runtime (by inspecting the properties/fields/etc), you often need code-generation instead, i.e. code that explicitly knows how to serialize each of your types. Tedious, and painful if you want to serialize something that doesn't have a twin.
Likewise, there is nowhere to store additional metadata about properties etc, so you end up having lots of additional code, or external configuration files. Something as simple as being able to associate a friendly name with a property (via an attribute) is a huge win for UI code.
Metaprogramming
.NET reflection also provides a mechanism to create types (etc) at runtime, which is hugely powerful for some specific scenarios; the alternatives are:
essentially running a parser/logic tree at runtime (rather than compiling the logic at runtime into executable code) - much slower
yet more code generation - yay!
I think to understand the need for reflection in .NET, we need to go back to before .NET. After all, modern languages like like Java and C# do not have a history BF (before reflection).
C++ arguably has had the most influence on C# and Java. But C++ did not originally have reflection and we coded without it and we managed to get by. Occasionally we had void pointer and would use a cast to force it into whatever type we wanted. The problem here was that the cast could fail with terrible consequences:
double CalculateSize(void* rectangle) {
return ((Rect*)rectangle)->getWidth() * ((Rect*)rectangle)->getHeight());
}
Now there are plenty of arguments why you shouldn't have coded yourself into this problem in the first place. But the problem is not much different from .NET 1.1 with C# when we didn't have generics:
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
However, when the C# example fails it does so with a exception rather than a potential core dump.
When reflection was added to C++ (known as Run Time Type Identification or RTTI), it was hotly debated. In Stroustrup's book The Design and Evolution of C++, he lists the following
arguments against RTTI, in that some people:
Declared the support unnecessary
Declared the new style inherently evil ("against the spirit of C++")
Deemed it too expensive
Thought it too complicated and confusing
Saw it as the beginning of an avalanche of new features
But it did allow us to query the type of objects, or features of objects. For example (using C#)
Hashtable shapes = new Hashtable();
....
double CalculateSize(object shape) {
if(shape is Rect) {
return ((Rect)shape).Width * ((Rect)shape).Height;
}
else if(shape is Circle) {
return Math.Power(((Circle)shape).Radius, 2.0) * Math.PI;
}
}
Of course, with proper planning this example should never need to occur.
So, real world situations where I've needed it include:
Accessing objects from shared memory, all I have is a pointer and I need to decide what to do with it.
Dynamically loading assemblies, think about NUnit where it loads every assembly and uses reflection to determine which classes are test fixtures.
Having a mixed bag of objects in a Hashtable and wanting to process them differently in an enumerator.
Many others...
So, I would go as far as to argue that Reflection has not enabled the ability to do something that couldn't be done before. However, it does make some types of problems easier to code, clearer to reader, shorter to write, etc.
Of course that's just my opinion, I could be wrong.
I once wanted to have unit tests in a text file that could be modified by a non-technical user in the format in C++:
MyObj Function args //textfile.txt
But I couldn't find a way to read in a string and then have the code create an object instance of the type represented by the string without reflection which C++ doesn't support.
char *str; //read in some type from a text file say the string is "MyObj"
str *obj; //cast a pointer as type MyObj
obj = new str; //create a MyObj
Another use might be to have a generic copy function that could copy the members of an class without knowing them in advance.
It helps a lot when you are using C# attributes like [Obsolete] or [Serializable] in your code. Frameworks like NUnit use reflection on classes and containing methods to understand which methods are tests, setup, teardown, etc.
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.