I'm searching for a way to write less sameish looking code and I'm not sure if there is a solution for this. So far I tried using Visual Studio Snippets, but that was not as helpful as needed. I would love to have C-Style Macros for this, or even better using C# language features.
Here is what I'm currently working on and the problem I have with it:
I'm writing full feature tests for an embedded device with a Web-UI in C#. I'm using Selenium to interact with the UI and have written some small classes to interact with custom input elements. The UI has many pages on which different controls are visible and naturally I created a class for each page and added all the input element classes for each controllable element.
This looks something like this (input element would be the Switch and ValueInput class):
public class SomePage : Page
{
protected const string id = "page_id";
#region ContentControls
protected Switch time_limit_enable;
protected ValueInput time_limit;
// and more ...
#endregion
internal SomePage() : base(id) { }
protected override void Init()
{
time_limit_enable = new Switch("time_limit_enable_id");
time_limit = new ValueInput("time_limit_id");
// and more ...
}
#region GetterSetter
public bool TimeLimitEnable
{
get => time_limit_enable.State;
set
{
if (time_limit_enable.State != value)
time_limit_enable.Toggle();
}
}
public string TimeLimit
{
get => time_limit.Text;
set => time_limit.Text = value;
}
// and more ...
#endregion
}
While this example page is small, the real pages have a lot more elements often of the same type (Switch, ValueInput, and more). The only thing that I want to specify is the element class, the id of the element, and the name. Some element classes have a template parameter as well. So basically the construction of the element. Is there some way to automate everything else?
Meaning:
creating a protected element
Initializing it in the Init() function
Adding a property getter and setter, named like the element in CamelCase. This property template would be different for different element classes.
Possible solutions:
Make the element class directly public readonly. Sounds ok, but then I would expose the different interfaces to the test side. I like that every property can be read and read directly with =. I could implement this in each element class though.
I could write a Code generator to do this, but that would be overkill. I'm probably looking at this from the wrong angle.
I could hack C-Style macros in c#, but that's just wrong.
I feel a little bit lost in the weeds. The solution is probably straightforward and obvious.
Related
I'm using .NET 2.0 so do not have access to automatic properties. So I must resort to the following way of coding private variables and public properties
private string m_hello = null;
public string Hello
{
get{return m_hello;}
set{m_hello = value;}
}
For methods of the containing class of the above private/public members, is there anyway to restrict access to the private variable? I do not like that I can either use m_hello or Hello.
Thanks.
As others have suggested this should be an answer...
You can still use automatic properties in C# 3 when targeting .NET 2.0, along with quite a few other C# 3 features. Unlike (say) expression trees, automatic properties don't need anything special from the CLR or the framework, beyond the [CompilerGenerated] attribute (which was introduced in .NET 2.0).
So if you're using VS2008 or VS2010, then it would be worth using an automatic property.
For what it's worth though, I'd like this ability too. I'd like to be able to scope variables within a property:
public string Name
{
private string name;
get { return name; }
set { name = value; }
}
I view this a bit like making a private variable readonly - it makes no difference to clients, but it helps to enforce correctness within the class code itself.
You can accomplish this via inheritance:
abstract class A // A is not instantiatable due to being abstract
{
private string m_hello = null;
public string Hello
{
get{return m_hello;}
set{m_hello = value;}
}
}
class B : A
{
// B now cannot access the private variable, use B in your code instead of A
}
I am not claiming that this is good. Just that it can be done.
No there is not a way to do that, other than to simply follow your own convention and do this.Hello if you really need to go through your public property.
I don't see why you would need/want to do this either, as since it is your internal class, you are the one in control of the code and you can define what/how it is used, so there shouldn't be an issue.
No. Any method inside the class will have access to both.
Your team should standardize on which to use (Property or private variable).
Once you decide which to use, you could try to use a custom FxCop rule to enforce the standard.
No, basically. Well, you could do something with compiler warnings via [Obsolete] and #pragma, but that would be excessive.
You could probably do it with tooling, but eventually you need to trust people not to do stupid things. After all, do you have special rules about:
while(true) { }
or do you just put that down to "don't be stupid"? ;p
You should only access the property through the public Hello property. This is the reason for this pattern. If you add any functionality to the get or set, if you are accessing the private instance, you will introduce bugs into your code. But the anwer is NO, you cannot prevent someone from calling the Private when they are inside your class changing your code.
Personally, I see nothing wrong with accessing the private member within the class. In fact that's what I typically do (unless there's logic within the property getter/setter that I always want to leverage).
It just makes sense to me: the code within the class constitutes that class's implementation; why hide an implementation from itself?
Here's an example of what I mean. Suppose I have some member, m_denominator, and I want it never to be zero:
private int m_denominator = 1;
public int Denominator
{
get { return m_denominator; }
set
{
if (value == 0)
throw new ArgumentException("Denominator must not be zero.");
m_denominator = value;
}
}
I might say to myself: "OK, everywhere I set this value within this class, I should use Denominator to make sure I'm not setting it to zero." But I'm completely in control of what I'm setting Denominator to -- I'm inside the class! In this scenario, the point of the logic in the Denominator property is to protect the class from invalid values set by client code. There's no excuse for setting your internal state to some invalid value within the implementation of a class itself.
Of course this is not an absolute rule. There are surely times when using the property for its logic within a class may be a sensible choice as a protective measure; really, I'm just arguing that it's not wrong to access private members from within a class.
If you find yourself wanting to hide details from yourself, that may be a code smell that your class has too many responsibilities. Consider extracting one of the responsibilities into a new class.
I believe in C#10, or at least a proposal for it, you can use semi-auto properties.
We can now use the field keyword in place of a backing property field.
So this:
private int _theNumber;
public int TheNumber
{
get => _theNumber;
set => _theNumber = value;
}
Becomes this:
public int TheNumber
{
get => field;
set => field = value;
}
Granted in the example I provided an auto property would make more sense, but I wanted to show a simple example.
I want to run through a series of steps that comprise a complete test. Some of these steps are automatic (so informational) and others require user interaction. Test steps are not known at compile time, they are using MEF to be loaded.
Currently I have something like
public abstract class TestRunnerBase
{
public abstract void Run();
}
With a list of steps like this:
List<TestRunnerBase> Steps = new List<TestRunnerBase>();
So all data representing a test serializable and that works okay so far. However what I really need is for a user to load a test from XML, it then walks them through the options displaying information on screen and gathering results.
But trying to work out how to create a control for data that is unknown at compile time has ended up with me getting a bit stuck on the best approach.
I am thinking to do this I would have a list of custom controls (1 a step) and the GUI would display the first step, wait for that control to be complete (I was thinking here that a raised event might work?) and then display the next if available and so on until the test is complete.
So is it possible to do this in WPF? Can you create a stack of controls in WPF that can each raise the same event to the parent container or is there a better way to do it?
But if I also use the abstract class I can't then derive a control from it also as no multiple inheritance in C# of course.
I would use MVVM and create a viewmodel that understood how to navigate the list of steps, providing a wizard type structure (prev/next) and exposing the current step.
I assume that while you have different kinds of potentially unknown steps that you have a concrete set of input options (bool, text, date, int, etc) then you could use a abstract property on your TestRunnerBase that identifies what kind of input is required (or none) using an enum that must be overriden.
Then you could use datatemplates and/or data triggers to control what is shown for each step of the test. The main viewmodel could check that conditions are right for going to the next step (perhaps a validate on your test).
Some psuedo code to get you thinking:
public enum TestInput
{
None,
Bool,
Text
}
public abstract class TestRunnerBase
{
public abstract TestInput TestInput { get; }
public bool BoolInput { get; set; }
public string TextInput { get; set; }
public abstract bool CanRun()
public abstract void Run();
}
public class MainViewModel
{
List<TestRunnerBase> Steps = new List<TestRunnerBase>();
public TestRunnerBase CurrentStep {get;set;};
public MainViewModel()
{
//loads the Steps
CurrentStep = Steps
}
public Command RunStepCommand
{
if (CurrentStep.CanRun())
{
CurrentStep.Run();
CurrentStep = Steps.Next(); //you get the idea
}
}
}
For your XAML you would bind a ContentPresenter to CurrentStep and use a datatemplate (and maybe data triggers) to control what is visible to the user (and of course bound to the UI).
In WPF you can dynamically create controls using XAML. Simply create a XAML snippet with the layout you want (either programatically or by hand) and use XamlReader.Parse to create the entire tree from the snippet. The returned object can then be inserted somewhere in the visual tree of your window.
To generate events from the visual tree generated by XamlReader you can use routed events.
Given a superclass which I cannot change which defines a certain property, how am I best to set the default value of it in a subclass?
Say, for example, that I am subclassing System.Windows.Forms.ToolStripButton and want to set a default value for the Text property. (For a more complex example, I also want to define the click handler, e.g.
Click += new EventHandler(click).) How am I best to do that?
Some ideas that I have had:
Set it in the constructor. But with multiple constructors, is that feasible? (I haven't got a firm grasp on how the constructors play with one another yet. Can I just update one and have them all Just Work™?)
Set it as a field, i.e. public string Text = "foo"; as I expected, this doesn't work.
Always call a certain method to set these values (I might name it, for example, InitializeComponent).
Ideally, I would be subclassing this class further and would be wanting to define the default values in it. I guess for that side I'd have protected fields and have the constructor or method read those values and assign them.
Is there some other way that hasn't occurred to me?
Or does my design not seem the right way around? I could also use a different class and work with a ToolStripButton instance inside it—aggregation rather than inheritance. (The more I think about this, the more it feels like it might be the right answer.)
It's the sort of thing that I know precisely how to do in Python, but doesn't look likely to be very elegant in C# (I know: different styles of language, tradeoffs, etc.; I'm not criticising C#).
Constuctor is probably the easiest route. You can always daisy-chain the constructors if it is a problem, for example:
public Foo() : this(12, "abc") {}
public Foo(int bar, string name) {
this.bar = bar;
this.name = name;
}
The other option is explicit properties (not auto-props) and field initialisers:
private int bar = 12;
public int Bar {
get { return bar; }
set { bar = value; }
}
In either case, you should consider adding [DefaultValue(...)] to the property, so that bindings (UI, serializers, etc) know about it. In this case, [DefaultValue(12)].
I'm creating a lookup class so a constant value will be used throughout all the projects.
The thing is, there are several solutions to create such a thing. I could create a single class with enums, structs or constants in it or create a single class for every 'object'. I'm wondering what would be the best solution.
First I thought doing something like this:
public static class Defines
{
public enum PAGELAYOUT_NAMES
{
STANDARD = "Standard"
}
}
But personally I don't like using strings in enums that much.
Another option would be to use a struct, which is even more ugly if you see the code:
public static class Defines
{
public struct PAGELAYOUT_NAMES
{
public static string STANDAARD = "Standaard";
}
}
This looks a bit better, but could be confusing when having a lot of options:
public static class Defines
{
public const string PAGELAYOUT_NAMES_STANDARD = "Standard";
}
While typing this post, I think this will be the best/clean option:
public static class PageLayout
{
public const string STANDARD = "Standard";
}
Any other suggestions?
Filling up the project with several classes which only define some constants seem to me like a lot of overhead and clutter.
Edit
It wasn't very clear in the original context, but the lookup values aren't limited to only strings. Some very good suggestions below are only possible when you use only strings, but Int's, DateTime and other types need to be supported also. Got some nice ideas from the answers here, I'll try out which one will work best in my current project.
Final implemented solution
Thanks to the suggestions below, I've implemented the lookup classes like this:
internal class Base<T>
{
internal T Value{ get; private set;}
internal Base(T value)
{
Value = value;
}
}
public class PageLayout
{
public static string Standard { get { return new Base<string>("Standard").Value; } }
}
This is based on an answer given below.
Reason is because now I can use this for non-strings & integers also, which isn't really possible with an enum with a description and a resource file, even though that would feel cleaner to me.
Depending on what exactly it is you're doing, you probably want to look at Resources.
You define an xml file (or use the designer to help you), and it gets compiled into an assembly (either embedded, or a "satellite assembly").
Right-click the properties node under your class library in the solution explorer, click "Open" and go to the resources tab. It's pretty simple to get started from there.
Once it's set up, it's easy to get at the values from code e.g:-
String s = Resources.PageLayoutNames.Standard;
There are a few complications, but without knowing more about your app I can't advise more. The one that comes to mind is if you're unit testing ASP.NET applications you need to make sure that the resource gets embedded rather than deployed as a satellite otherwise the unit tests don't work.
They're also used for globalisation, so it's good to be familiar with them.
Edit:
Alternately after reading your question again, I'm inclined to ask "What do you need the string for at all?".
What are you doing that you can't do with just an enum?
enum PageLayouts
{
Standard,
ExtraAwesome
}
If you're trying to map text for display to an enum type, there are a bunch of ways to do that e.g. by using the DescriptionAttribute
enum PageLayouts
{
[Description("Standard")]
Standard,
[Description("Extra Awesome")]
ExtraAwesome
}
You can't give the DescriptionAttribute a resource key out of the box, though. You have to subclass it if you want to support globalisation...
I prefer this way using a factory style static properties. But it depends on the exact scenario. You can use string or enum as the field.
public class PageLayout
{
private readonly string LayoutType;
private PageLayout(string layoutType)
{
LayoutType = layoutType;
}
public static Standard {get {return new PageLayout("Standard");}}
}
Then in calling code use PageLayout.Standard
People advise against public nested classes, so in your earlier examples Defines should be a namespace rather than an outer class.
I always use the
public static class PageLayout
{
public const string STANDARD = "Standard";
}
approach.
I do however create more classes than one: When i use a lot of sessionvariables, i create a (public static)
class SessionNames
And i do make a difference between soultion wide constants and project wide constants.
sometimes the constants for one project (for example 20 placeholders in a PDF you have to create) have nothing to do with the other projects so i make that a project class, but when i have solution wide constants i create a class at the same place as i put my string extensions etc.
I'm using .NET 2.0 so do not have access to automatic properties. So I must resort to the following way of coding private variables and public properties
private string m_hello = null;
public string Hello
{
get{return m_hello;}
set{m_hello = value;}
}
For methods of the containing class of the above private/public members, is there anyway to restrict access to the private variable? I do not like that I can either use m_hello or Hello.
Thanks.
As others have suggested this should be an answer...
You can still use automatic properties in C# 3 when targeting .NET 2.0, along with quite a few other C# 3 features. Unlike (say) expression trees, automatic properties don't need anything special from the CLR or the framework, beyond the [CompilerGenerated] attribute (which was introduced in .NET 2.0).
So if you're using VS2008 or VS2010, then it would be worth using an automatic property.
For what it's worth though, I'd like this ability too. I'd like to be able to scope variables within a property:
public string Name
{
private string name;
get { return name; }
set { name = value; }
}
I view this a bit like making a private variable readonly - it makes no difference to clients, but it helps to enforce correctness within the class code itself.
You can accomplish this via inheritance:
abstract class A // A is not instantiatable due to being abstract
{
private string m_hello = null;
public string Hello
{
get{return m_hello;}
set{m_hello = value;}
}
}
class B : A
{
// B now cannot access the private variable, use B in your code instead of A
}
I am not claiming that this is good. Just that it can be done.
No there is not a way to do that, other than to simply follow your own convention and do this.Hello if you really need to go through your public property.
I don't see why you would need/want to do this either, as since it is your internal class, you are the one in control of the code and you can define what/how it is used, so there shouldn't be an issue.
No. Any method inside the class will have access to both.
Your team should standardize on which to use (Property or private variable).
Once you decide which to use, you could try to use a custom FxCop rule to enforce the standard.
No, basically. Well, you could do something with compiler warnings via [Obsolete] and #pragma, but that would be excessive.
You could probably do it with tooling, but eventually you need to trust people not to do stupid things. After all, do you have special rules about:
while(true) { }
or do you just put that down to "don't be stupid"? ;p
You should only access the property through the public Hello property. This is the reason for this pattern. If you add any functionality to the get or set, if you are accessing the private instance, you will introduce bugs into your code. But the anwer is NO, you cannot prevent someone from calling the Private when they are inside your class changing your code.
Personally, I see nothing wrong with accessing the private member within the class. In fact that's what I typically do (unless there's logic within the property getter/setter that I always want to leverage).
It just makes sense to me: the code within the class constitutes that class's implementation; why hide an implementation from itself?
Here's an example of what I mean. Suppose I have some member, m_denominator, and I want it never to be zero:
private int m_denominator = 1;
public int Denominator
{
get { return m_denominator; }
set
{
if (value == 0)
throw new ArgumentException("Denominator must not be zero.");
m_denominator = value;
}
}
I might say to myself: "OK, everywhere I set this value within this class, I should use Denominator to make sure I'm not setting it to zero." But I'm completely in control of what I'm setting Denominator to -- I'm inside the class! In this scenario, the point of the logic in the Denominator property is to protect the class from invalid values set by client code. There's no excuse for setting your internal state to some invalid value within the implementation of a class itself.
Of course this is not an absolute rule. There are surely times when using the property for its logic within a class may be a sensible choice as a protective measure; really, I'm just arguing that it's not wrong to access private members from within a class.
If you find yourself wanting to hide details from yourself, that may be a code smell that your class has too many responsibilities. Consider extracting one of the responsibilities into a new class.
I believe in C#10, or at least a proposal for it, you can use semi-auto properties.
We can now use the field keyword in place of a backing property field.
So this:
private int _theNumber;
public int TheNumber
{
get => _theNumber;
set => _theNumber = value;
}
Becomes this:
public int TheNumber
{
get => field;
set => field = value;
}
Granted in the example I provided an auto property would make more sense, but I wanted to show a simple example.