Lookup class use enum, struct, public const, something else? - c#

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.

Related

Factory pattern with objects that have many optional properties

I'm refactoring a class that represents the data in some XML. Currently, the class loads the XML itself and property implementations parse the XML every time. I'd like to factor out the XML logic and use a factory to create these objects. But there are several 'optional' properties and I'm struggling to find an elegant way to handle this.
Let's say the XML looks like this:
<data>
<foo>a</foo>
<bar>b</bar>
</data>
Assume both foo and bar are optional. The class implementation looks something like this:
interface IOptionalFoo
{
public bool HasFoo();
public string Foo { get; }
}
// Assume IOptionalBar is similar
public class Data : IOptionalFoo, IOptionalBar
{
// ...
}
(Don't ask me why there's a mix of methods and properties for it. I didn't design that interface and it's not changing.)
So I've got a factory and it looks something like this:
class DataFactory
{
public static Data Create(string xml)
{
var dataXml = new DataXml(xml);
if (dataXml.HasFoo())
{
// ???
}
// Create and return the object based on the data that was gathered
}
}
This is where I can't seem to settle on an elegant solution. I've done some searching and found some solutions I don't like. Suppose I leave out all of the optional properties from the constructor:
I can implement Foo and Bar as read/write on Data. This satisfies the interface but I don't like it from a design standpoint. The properties are meant to be immutable and this fudges that.
I could provide SetFoo() and SetBar() methods in Data. This is just putting lipstick on the last method.
I could use the internal access specifier; for the most part I don't believe this class is being used outside of its assembly so again it's just a different way to do the first technique.
The only other solution I can think of involves adding some methods to the data class:
class Data : IOptionalFoo, IOptionalBar
{
public static Data WithFoo(Data input, string foo)
{
input.Foo = foo;
return input;
}
}
If I do that, the setter on Foo can be private and that makes me happier. But I don't really like littering the data object with a lot of creation methods, either. There's a LOT of optional properties. I've thought about making some kind of DataInitialization object with a get/set API of nullable versions for each property, but so many of the properties are optional it'd end up more like the object I am refactoring becomes a facade over a read/write version. Maybe that's the best solution: an internal read/write version of the class.
Have I enumerated the options? Do I need to quit being so picky and settle on one of the techniques above? Or is there some other solution I haven't thought of?
You can think of such keywords as virtual/castle dynamic proxy/reflection/T4 scripts - each one can solve the problem on a slightly different angle.
On another note, this seems perfectably reasonable, unless I misunderstood you:
private void CopyFrom(DataXml dataXml) // in Data class
{
if (dataXml.HasFoo()) Foo = dataXml.Foo;
//etc
}
What I did:
I created a new class that represented a read/write interface for all of the properties. Now the constructor of the Data class takes an instance of that type via the constructor and wraps the read/write properties with read-only versions. It was a little tedious, but wasn't as bad as I thought.

Using constants or global variables in 3 tier console application

I have a 3 tier application setup like so with a console presentation layer. In my business logic I have a class where I declare a number of different variables that are fixed i.e. the values won't change. The values of these variables are taken from app settings.
Now the problem I'm finding is that my class calls off to different methods where these variables are being passed around via the method signatures. Is this good practice? If not, would it not be better using constants instead? If so, where should the constants live so I can access them where ever I need them rather than passing variables around?
EDIT
Adding some code for you guys. So they're global variables I am referring to here.
OK so in my console app (presentation), I currently have something like this:
public class Program
{
public static void Main(string[] args)
{
MainClass myClass = new MainClass(appSetting1, appSetting2, appSetting3);
}
}
Then in MainClass I have:
public class MainClass
{
private string _appSetting1 = string.Empty;
private string _appSetting2 = string.Empty;
private string _appSetting3 = string.Empty;
public MainClass(string appSetting1, string appSetting2, string appSetting3)
{
_appSetting1 = appSetting1;
_appSetting2 = appSetting2;
_appSetting3 = appSetting3;
}
public void MyMethod()
{
Method2(_appSetting1, _appSetting2);
Method3(_appSetting2, _appSetting3);
Method4(_appSetting1, _appSetting3);
}
}
I hope you can see what I mean. I'm finding myself passing around global variables across multiple methods. I just thought there would be an easier way of doing this? Such as creating a constants class or something on the lines of that? I'm not 100% sure of the best approach to go for.
In my MainClass I could just declare my global variables like this:
private string _appSetting1 = ConfigurationManager.AppSettings["appsetting1"];
private string _appSetting2 = ConfigurationManager.AppSettings["appsetting2"];
private string _appSetting3 = ConfigurationManager.AppSettings["appsetting3"];
But do I really want to be doing that in my business logic?
Another possibility is to create a Settings class that loads them and exposes them as public readonly. This has worked well for me in the past:
public class Settings
{
public static readonly string AppSetting1;
public static readonly string AppSetting2;
public static readonly string AppSetting3;
static Settings()
{
AppSetting1 = ConfigurationManager.AppSettings["appsetting1"];
AppSetting2 = ConfigurationManager.AppSettings["appsetting2"];
AppSetting3 = ConfigurationManager.AppSettings["appsetting3"];
}
}
The static constructor is called automatically before the first access to any of the variables, so you don't have to call it explicitly. Your program can access the variables as Settings.AppSetting1, etc.
I am of the config-free mindset.
If these things presumably don't change, then have an assembly that projects can reference that return the values.
I shy away from configuration files. I realise they are needed in deployment circumstances, but given that your requirement, I'd recommend a common class library that everything else can use and reference.
If you do have to change something supposedly constant, you change it in one place.
if they are in the app.config and shouldn't change you should always reference them from there rather than passing them as parameters. This way your intention that they are static values is clear in the code.
EDIT
Jims answer makes sense in that case. Its really just a short hand so instead of writing ConfigurationManager.AppSettings["appsetting1"]; you use Settings.AppSetting1. either way you would be repeating yourself if you declare them at the top every class into class level variables. I like Jim's answer better than mine though as you can extend it. I keep all config in the db and then use a singleton which has a proc call in the private instance constructor to load config. Jims answer could implement this later without you needing to change your calling code. Generally config files are a pain.

How to get all the properties of a specified type in a class without reflection

I have a class which is has tons of properties. Most of them are of custom types. I want to get all those properties, type of whose interface is same.
Public class abc:IamLegend
{
few properties
}
public class def:IamLegend
{
few properties
}
public class on_which_iamworking
{
public abc propabc{ get; set; }
public def propdef{ get; set; }
public someothertype propother{ get; set; }
}
I want something which returns propabc and propdef.
I know how to do it using reflection, but I am looking for another way.
I am working on c# 4.0
Thanks
I am afraid that this is not possible at runtime without using reflection. That's what reflection is designed for.
The main problem of reflection is that it is slow. If you don't want to use reflection only because of it's slowness, you could make caching of your property list in some static property or class. I used this tecknique widely in similar problems and there wasn't any problems with perfomance.
If you have holy war against reflection, you could create a special util that parses C# file (or builds your prokects, loads output assembly and use reflection, but only before build, not in run-time), finds needed properties and writes it into autogenerated file (maybe also C# code file) as static-class array-property initializer. And call that util on pre-build event of your project. Then you'll get all needed properties completely without reflections =) (but I wouldn't do that)
Well, there's two ways:
1/
return new List<string> { "propabc", "propdev" };
2/ Reflection :P
If you need to retrieve the list of properties many times and are afraid of the performance impact, compute the list only once and store it in a static property (as the list of properties of a class won't change during runtime).
There is an alternative approach for components. It is TypeDescriptor for classes that implement IComponent. I believe that is used by WPF.

Why are properties on classes in ASP.NET using C# generally public and properties using C# for desktop apps private?

I have searched high and low (and very possibly could have missed it), but in my years of programming, I have always come across one practice that seemed to be the standard in OOP, which is to use private properties in an object with public methods to manipulate the data.
However, the more I delve into ASP.NET (specifically with MVC), the more public properties I see inside of classes (specifically models) such as the ones shown at Scottgu's blog discussing the Entity Framework.
Does it have something to do with the way that LINQ populates a class?
Thanks in advance, and the answer may be out there, but I have been looking for a long time, and can't figure out why ASP.NET uses public and even the desktop C# apps use private.
You are confusing fields with properties. The concept of a property in .NET languages is basically an encapsulation of the get and set functions that you're describing.
For instance:
private int foo;
public int FooProperty
{
get { return foo; }
set { foo = value; ]
}
This is analagous to what you'd see otherwise like this:
private int foo;
public int getFoo()
{
return foo;
}
public int setFoo(int value)
{
foo = value;
}
It basically provides syntax that's similar to that of an ordinary field while providing the developer with control over the actual get and set behavior.
What may be further confusing you is that C# has a shorthand for automatic implementation of simple properties (like the one above). Doing this:
public int Foo { get; set; }
Is actually just a shorthand for this:
private int _foo;
public int Foo
{
get { return foo; }
set { foo = value; }
}
This allows you to use properties everywhere in your public-facing API without sacrificing the convenience of fields. This means that you can
Be consistent (all public members are exposed through properties, instead of a mix of properties and fields
Be flexible, so you can change the code behind the property to a full property at a later date (if the need arises) without changing the public-facing API and having to recompile any assemblies that referenced your type.
I think what you might be seeing is the Auto-Implement Property feature. This is a shortcut to expose data members as public so that you don't need to explicitly create a private data members. C# will creates a private data member for you.
Eg:
public string MyProperty { get; set; }
Is doing the same as:
public string _MyProperty;
public string MyProperty
{
get { return _MyProperty; }
set { _MyProperty = value; }
}
You could make your data members public and not use the shortcut but if you decided to change the implementation of the data member to have some logic then you would need to break the interface.
Be careful not to confuse Properties with Member variables. The standard in OOP was to have private "properties" when there was no concept of a property, only a member variable, then to wrap that member variable in a public method to get and set it's value. It's generally a bad idea to have a public member variable, but public properties are good practice because just like methods, they encapsulate your member variable.
It's also to do with how ASP.Net (and possibly also WPF, by extension? I don't know WPF but one could make a reasonable assumption) decides using reflection what you mean when you pass a string to it's databinding functions.
Given the following:
public class ImaginaryModel
{
public string Naomi { get; set; }
public string GetHeidi()
{
// do something here
}
public string Elle;
}
This databinding expression will work:
Eval("Naomi")
... whereas these will not:
Eval("GetHeidi")
Eval("Elle")
... because the implementation of databinding evaluation appears to be written against Type.GetProperties(). At least, this is my experience and understanding. The convention probably grew out of this.
Public Properties are the way the .NET community has elected to deal with this.
Note the difference here:
public int Property { get; set; } // C# auto-prop
public int Property; // C# "field"
The former is the standard way, and is generally accepted. A backing field can be added when necessary. The latter is typically avoided, since it doesn't have the get/set.
It's possibly a relic due to the nature of Asp.net WebForms - Properties on code-behind had to be protected at minimum, as the asp.net compiler generates wrapper classes for pages and user controls. The generated classes cannot access private properties, so protected or public is generally the way to go.
Since I'm not an MVC expert, I can't say for certain whether this still occurs in MVC - but I do know that in WinForms, the codebehind is just a partial class and there is no generation of a wrapper object, any private property is fully accessible by textboxes and the like.
Alternately, people could just be using public properties so they can more easily create proxy classes in unit testing environments (which is the main reason I would use them on a model).

Singletons and constants

I am making a program which makes use of a couple of constants. At first, each time I needed to use a constant, I'd define it as
//C#
private static readonly int MyConstant = xxx;
//Java
private static final int MyConstant = xxx;
in the class where I'd need it. After some time, I started to realise that some constants would be needed in more than one class.
At this time, I had 3 choises:
To define them in the different classes that needed it. This leads to repetition. If by some reason later I need to change one of them, I'd have to check in all classes to replace them everywhere.
To define a static class/singleton with all the constants as public.
If I needed a constant X in ClassA, ClassB and ClassC, I could just define it in ClassA as public, and then have ClassB and ClassC refer to them. This solution doesn't seem that good to me as it introduces even more dependencies as the classes already have between them.
I ended up implementing my code with the second option.
Is that the best alternative? I feel I am probably missing some other better alternative.
What worries me about using the singleton here is that it is nowhere clear to a user of the class that this class is using the singleton. Maybe I could create a ConstantsClass that held all the constants needed and then I'd pass it in the constructor to the classes that'd need it?
Thanks
edit: I'm using this mostly for complex types, not ints and strings. At least in the C# case that makes a difference as it means I can't use the const keyword.
No wording about C#, but in Java there are several ways to solve this problem.
Change the access modifier to default (package-only) or public. The most straightforward solution.
Group them in a package-private or public enum. Most straightforward if those values are related to each other. E.g. Role.ADMIN, Role.USER, Role.GUEST, etc.
Declare them in a package-private or public interface and let the classes implement it. Only do this if those constants belong to some contract the classes have to adhere as well.
Put them in properties files and load as private static final Properties and add a public static String getProperty(String key). Wrap this in some package-private or public Configuration class. More useful if those constants might be sensitive to changes which you could then control externally.
Constants doesn't require to be accessed by an instance, so the whole singleton idea makes no sense.
Use a properties file and put the constants in there.
ConfigurationManager.AppSettings Property in .Net exists for just this reason. You put the settings into config files assuming that these are elements that you want to be set in one place,e.g. for a website using ASP.Net the web.config is one location where settings can be placed so that development, test and production environments can each have different settings in how they run.
As far as int is concerned I usually use an enum in C#
public enum MyMagicNumbers
{
TheFirst = 1,
TheSecond = 2,
TheLast = 10,
}
For other types - like BalusC already mentioned - a sealed class is all you need
public sealed class MyMagicStuff
{
private MyMagicStuff() {}
public const string TheFirst = "One";
public const string TheSceond = "Two";
public const string TheLast = "Ten";
}
I'd define it in one place, in one of the classes that needed it. I'd make it static and final and public so it was true constant, accessible by any other client that needed it.
One approach to this would be to use Spring, available in both Java and .NET.
www.springsource.org
www.springframework.net - .net
Otherwise I'd use a config file.

Categories