I've two Classes
public class DemoProperty
{
public int ID { get; set; }
public string Title { get; set; }
public string MenuCode { get; set; }
public string OriginalURL { get; set; }
}
public class MyCommonProperties
{
private static List<DemoProperty> _DemoList;
public static List<DemoProperty> DemoList
{
get { return _DemoList; }
set { _DemoList = value; }
}
}
My need is to keep some common data throughout the project.For that I've using an application variable and it holds a Dictionary<string,List<DemoProperty>>.
Global.asx
void Application_Start(object sender, EventArgs e)
{
Application["DemoProperty"] = new Dictionary<string,List<DemoProperty>>();
MyCommonProperties.DemoList= (Dictionary<string,List<DemoProperty>>)Application["CommonProperties"];
}
Actually I don't know more about its demerits. If it is a bad idea could you please suggest me a good one.
What the static keyword ensures, is that the specific property / class exists only once in your application.
If this is bad or not is a very general question to which the answer unfortunately seems to be "it depends". Ultimately it is a question how you want to design you program.
Making something static can however make automatic testing harder, because you can not easily decouple your program into smaller testable parts (as all parts directly interact with your static data). It also makes reading the code harder, because it could be hard to understand when and what modifies the global data.
I will try an example to underline this:
class Data {
public static string Entry;
}
class Operations {
void SetOne() {
Data.Entry = "one";
}
}
With this example, for someone calling SetOne() it might be non-obvious that the method actually sets something in Data.
Another approach could be:
class Data {
public string Entry;
}
class Operations {
void SetOne(Data data) {
data.Entry = "one";
}
}
Now for the caller its is more obvious that Data is used in some way by the method, because the call now looks like SetOne(data).
In my humble personal experience static was almost never a good idea. While it might make things quicker in the short run, its drawbacks concerning readability & testability of your code are usually too big to ignore.
Related
I'm in the middle of creating a new library, and as I was building it something seemed a little odd.
Here's the code:
namespace traditional_poker
{
public class poker
{
public class hand
{
public String Name
{
get; set;
}
public String[] cards
{
get; set;
}
}
List<hand> players;
public void AddPlayer(String name)
{
hand newHand = new hand();
newHand.Name = name;
players.Add(newHand);
}
}
}
I have List<hand> players inside the Library itself, which means the library is storing data (albeit temporarily).
Is this bad practice?
Is there a better way to do this?
Or is the way I'm doing it completely legitimate?
It all depends on the way you want to tackle the problem.
If you want to have the data temporarily then it is Ok, If you want to save your data between different application instances or across different sessions then you should use a data persistent tool (filing, databases, ...)
namespace traditional_poker
{
public class poker
{
public class hand // use PascalCaseNamingConvention
{
public String Name
{
get; set;
}
public String[] cards // use PascalCaseNamingConvention
{
get; set;
}
}
List<hand> players;
public void AddPlayer(String name)
{
hand newHand = new hand();
newHand.Name = name;
players.Add(newHand); //null reference exception here! you should initialize players
}
}
}
The library is not storing data.
It offers functionality, using classes, which have fields. These classes are instantiated by an application using them, in the application memory space.
If it were bad practice to have data 'stored' in libraries, then libraries would not have classes or variables, and be severely limited.
i know i lack a base knowlage of the realtions between classes and inheritance
i find it hard to understand a simple thing :
a given DDl or TextBox could be accessed from code behind
int selected = DDLID.SelectedIndex ;
string userInput = TBXID.Text;
Now from a class that is placed in code behind :
public static class ControlsValue
{
public static int UserSel = DDLID.Selected.index;
public static string UserText = TBXID.Text;
}
i was trying to "Arange" my code so i will be able to reuse it in some other projects
...so i have moved all global variables related to the code in that class into the class
and what i can't do is assign variables with webControls Values
what is the way to do it ?
update
a way i could think of is via parameter
public static class ControlsValue
{
public static void getValues(DropDownList DDLID)
{
public static int UserSel = DDLID.Selected.index;
}
public static string UserText(TextBox TBXID)
{
return TBXID.Text;
}
}
Create a different class like this
public class ControlValues{
private int_dropDownIndex;
public int DropDownIndex{
get { return _dropDownIndex; }
set { _dropDownIndex= value; }
}
private string _textBoxValue;
public string TextBoxValue{
get { return _textBoxValue; }
set { _textBoxValue= value; }
}
public ControlValues(int dropDownIndex, string textBoxValue){
this._dropDownIndex = dropDownIndex;
this._textBoxValue = textBoxValue;
}
}
You can create an instance from your code behind like below
ControlValues cv= new ControlValues(DDLID.Selected.index, TBXID.Text);
Now you can access the DropDown index and text as
cv.DropDownIndex;
cv.TextBoxValue;
Although I provided an answer for this, Please note:
Remember the stateless nature of web application and the way you are going to use this.
In ASP.NET, it will be inefficient to create an Instance of class to hold values of server control because those controls and their values are directly accessible from the code behind. Using this approach will be an extra overhead.
If you are serious about learning re-usability, I would strongly recommend you to learn basics of object oriented programming. Once you have a good grip of OOP, you will see clearly when to apply OOP principles.
I've got quite a number of classes, which have got the standard set and get methods. My problem is that many of these set methods should not be callable from outside the class which holds the objects. I'm not quite sure if there are any patterns or C# for lack of a better word - operations that would make this easier.
In reference to the code below, there are a number of classes similar to SecureSite, which the controller should be able to call functions or access variables to modify the SecureSite (and the other similar classes). However when the user asks to see SecureSite etc. they shouldn't be able to change this.
From my limited knowledge and the answers I've seen to similar questions on this site, the main issue appears to be that the Write_SecureSite can't be made fully immutable due to the List<String> AccessHistory variable. So, what I've come up with looks as ugly as a bulldogs backside and is just as messy. Essentially there is a Write version of the SecureSite class which contains a class within it, which returns a readonly version of the SecureSite class.
So, am I missing something magic in C# that would make this all so much easier?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ReadOnlyExample {
public class Write_SecureSite {
private List<String> mAccessHistory;
public List<String> AccessHistory {
get {
return mAccessHistory;
}
}
public SecureSite ReadOnly {
get {
return new SecureSite(this);
}
}
public class SecureSite {
public SecureSite(Write_SecureSite aParent) {
AccessHistory=aParent.AccessHistory;
}
public IEnumerable<String> AccessHistory;
}
}
public static class Controller {
private static Write_SecureSite SimpleSecureSite=new Write_SecureSite();
public static Write_SecureSite.SecureSite Login(String MyLogin) {
SimpleSecureSite.AccessHistory.Add(MyLogin);
return SimpleSecureSite.ReadOnly;
}
public static Write_SecureSite.SecureSite Details() {
return SimpleSecureSite.ReadOnly;
}
}
public static class User {
public static void Miscellaneous() {
Controller.Login("Me");
Write_SecureSite.SecureSite SecureSite=Controller.Details();
//Not going to happen.
SecureSite.AccessHistory.Add("Me2");
//No problem.
foreach(String AccessedBy in SecureSite.AccessHistory) {
Console.Out.WriteLine("Accessed By: "+AccessedBy);
}
}
}
}
I suggest to use interfaces:
public interface IReadSecureSite
{
IEnumerable<String> AccessHistory { get; }
}
class Write_SecureSite : IReadSecureSite
{
public IList<String> AccessHistoryList { get; private set; }
public Write_SecureSite()
{
AccessHistoryList = new List<string>();
}
public IEnumerable<String> AccessHistory {
get {
return AccessHistoryList;
}
}
}
public class Controller
{
private Write_SecureSite sec= new Write_SecureSite();
public IReadSecureSite Login(string user)
{
return sec;
}
}
...
Controller ctrl = new Controller();
IReadSecureSite read = ctrl.Login("me");
foreach(string user in read.AccessHistory)
{
}
This is not so much an answer as a direction to look into. I am also struggling with the Immutable class
So far I am using my constructors to set my read-only private vars
I am using methods to update my lists internally instead of exposing them as public properties: ie. use public Void Add(string itemToAdd)
I am reading a book by Petricek and Skeet called "Real World Functional Programming" and it is helping me move in the direction you are discussing
Here is a small tutorial from the same author's that introduces some basic concepts: http://msdn.microsoft.com/en-us/library/hh297108.aspx
Hope this helps a bit
Update: I probably should have been clearer: I was looking to point you in the direction of a more functional view as opposed to rewriting the class you had listed in your question - my apologies (removed sample)
So let's say I have a Clone object with these properties. Clone might have different mass or name based on the file it was loaded from, but these values never change at runtime. However, Clone instances to have some autonomy and properties which do change per instance, so they can't all be the same instance.
public class Clone
{
public float Mass { get; protected set; }
public string Name { get; protected set; }
public Clone(string filePath)
{
Name = //read name from file
Mass = //read mass from file
}
}
Now, what I want to know is, what are the benefits and drawbacks (if any) of doing this instead:
public class CloneInfo
{
public float Mass;
}
public static class Database
{
public static Dictionary<string, CloneInfo> Lookup;
[...load whole dictionary from files...]
}
public class Clone
{
public string Name { get; protected set; }
public float Mass { get { return Database.Lookup[Name].Mass; } }
public Clone(string name)
{
Name = name;
}
}
With this 'redirecting' method, I keep the simple syntax of Clone.Mass, but don't have to store a Mass value for each instance. Since I've got thousands of clones wandering about, this is a good thing. I'm mainly interested in 'redirecting' because of the syntax. I realize that I could simply manually do the database lookup every time I wanted a particular clone's mass, but I'd rather keep the usage of the class nice and straightforward. Is there any drawback to this? Is the property going to be slower than direct lookup in the static database? Does the property take up any space in a Clone instance?
Or, perhaps, is this a use case C# already has an answer for which I'm not aware of? Seems like write-once properties which are common among many instances might be somewhere in this beautiful language.
If all the clones of a certain type have the same mass, that sounds like a job for subclassing:
class Clone
{
public abstract float Mass { get; }
}
class HeavyClone : Clone
{
public override float Mass { get { return 12345.6; } }
}
class LightClone : Clone
{
public override float Mass { get { return 1.23456; } }
}
More to the point of your question: if you are more constrained by memory than by processing time, your approach may give some benefit. If memory is plentiful, and cache performance is not an issue, the approach you suggest probably has little value. It certainly seems to complicate the code quite a bit.
The usual advice is: write simple code, measure the performance, and, if the performance is inadequate, address the performance bottlenecks. That way, you only have complicated code in places where it actually helps your application's performance.
Another thought: instead of having have the clone index into the dictionary with the Name string, why not just have a CloneInfo field:
public class CloneInfo
{
public float Mass;
}
public class Clone
{
private CloneInfo _info;
public float Mass { get { return _info.Mass; } }
public Clone(CloneInfo info)
{
_info = info;
}
}
Suppose that we have a lot of accesses to Mass property. If in each access you try to load the Mass value from database, it can be a very heavy duty for your application and here will be a bottleneck. If the Mass value can be cached in the object, you can easily load it for once and keep it for further usages.
Trying to do everything by the book, is this correct?:
public class JollyHockey
{
public string AnotherCoolProperty { get { return anotherCoolProperty; } }
string anotherCoolProperty;
public JollyHockey(string anotherCoolProperty)
{
this.anotherCoolProperty = anotherCoolProperty;
}
}
Or do some people use underscores for the private class variables?
Some people (including myself) prefix private class variables with an underscore (simply as a visual indication of what is being used where).
This is mainly a personal (or team) level style consideration and you can use what you want (or what your team has standardized on).
Just be sure you're consistent!
For what it's worth, you could also use auto-properties for your example:
public class JollyHockey
{
public string AnotherCoolProperty { get; private set; }
public JollyHockey(string anotherCoolProperty)
{
AnotherCoolProperty = anotherCoolProperty;
}
}
Or you can do this:
public class JollyHockey
{
public string AnotherCoolProperty { get; private set; }
public JollyHockey(string anotherCoolProperty)
{
this.AnotherCoolProperty = anotherCoolProperty;
}
}
I believe that your example agrees with the MS coding guidelines. However, I don't like it, and this is something that can be agreed upon by your team.
The reason I don't like it is because the underlying field name often conflicts with method parameters. I use an underscore to make it clear that they are private variables.
When a function parameter has the same name as a private field,
I usually prefix the parameter with an underscore
I think it makes sense
the ReSharper thing By fletcher is a good idea