Easist way to pass strings in a console app - c#

I really wanted to just use
Class MyClasses
{
public string mwaAHA = "here";
//and then use it like this:
static void testStringhere()
{
console.writeline(mwaAHA);
}
}
I'm doing something wrong can someone demo the eaist way I can make a few strings and use them in any void?

Since your testStringhere() is static, it only has access to other static members residing in the same scope.
To solve your issue in this case use
public static string mwaAHA = "here";

The answer above is right, but it should probably also have a private and a const..something like:
private const string str = "here";

Related

Handling Nested Property Values

What is the elegant solution to access nested property values?
Example:
In some cases it could look as follows:
public void someFunction()
{
this.Device.ResponseHandler.Process(this.Device.TcpClient.responseMessage, this.Device.TcpClient.responseType)
}
My solution was to copy objects, just to shorten the names afterwards.
public void someFuntion()
{
// Just for shorten the access name afterwards
ResponseHandler responseHandler = this.Device.RepsonseHandler;
TcpClient tcpClient = this.Device.TcpClient;
responseHandler.Process(tcpClient.responseMessage, tcpClient.responseType);
}
It is mostly opinion based, but there are generally two ways:
The one you are using.
List every argument in new line:
public void someFunction()
{
this.Device.ResponseHandler.Process(
this.Device.TcpClient.responseMessage,
this.Device.TcpClient.responseType
);
}
IMO both are equally readable and in second approach you don't need another variables :)
You could add a usings at the top if you don't like long names:
using ResponseHandler = this.Device.ResponseHandler;
using TcpClient = this.Device.TcpClient;
public void someFunction()
{
ResponseHandler.Process(TcpClient.responseMessage, TcpClient.responseType);
}

How do I extend the String class?

Extending core classes in javascript is dead easy. I get the impression it's not quite so easy in C#. I was wanting to add some things to the String class so that I could do stuff like:
string s = "the cat's mat sat";
string sql = s.smartsingleQuote();
thus giving me
the cat''s mat sat
Is that even feasible, or do I have to write a function for that?
Yes it is possible using Extension Methods - MSDN
Here is a sample code.
public static class Extns
{
public static string smartsingleQuote(this string s)
{
return s.Replace("'","''");
}
}
Disclaimer : Not tested.
Yes you can do this, with an extension method. It'll look something like that:
public static class NameDoesNotMatter {
public static string smartSingleQuote(this string s) {
string result = s.Replace("'","''");
return result;
}
}
The magic is the keyword "this" in front of the first argument. Then you can write your code and it'll work:
string s = "the cat's mat sat";
string sql = s.smartsingleQuote();
You cannot accomplish exactly what you are talking about as the string class is sealed
You can accomplish the aesthetic of this by creating an extension method
public static class StringExtensions
{
public static string SmartSingleQuote(this string str)
{
//Do stuff here
}
}
The this keyword in the parameter allows you to take that parameter and put it in front of the method name for easier chaining like you requested done in your question. This, however, is equivalent to:
StringExtensions.SmartSingleQuote(s);
It just depends on your preference at that point :)
Here is a good SO answer on extension methods

How to create a Constant Static Array?

I have a static string class for my database so that I always spell the tables and columns they way they were designed.
I've currently got about 500 lines of code in this one class, but here is a short example:
public const string PURCHASING = "PURCHASING";
public const string SCHED_PURCH = "SCHED/PURCH";
public const string SCHEDULING = "SCHEDULING";
To create a readonly static string array of the "Clerk" department, I use this static declaration:
public static string[] CLERK_DEPT {
get {
return new string[] { PURCHASING, SCHEDULING, SCHED_PURCH };
}
}
There are many lines of code like this in my database strings class.
Today, I happened across this active post where someone was doing something very similar:
How do I prevent the modification of a private field in a class?
The answer there provided a way to provide a readonly string array that I had not considered before:
You must return a copy of your array.
public String[] getArr() {
return arr == null ? null : Arrays.copyOf(arr, arr.length);
}
That has me wondering now if someone out here knows of a more efficient way of passing back my readonly string array.
I must admit that I've always abhorred the idea of the return new string[] in my code.
So, is there? ...a more efficient and cleaner way of doing this or have I already created the best solution?
There's no such thing as an immutable array, basically.
If you trust all your callers, you could tell them not to mutate the array. An alternative is to provide a read-only wrapper:
private static readonly ReadOnlyCollection<string> clerkDepartments =
new ReadOnlyCollection<string>(
new[] { "PURCHASING", "SCHED/PURCH", "SCHEDULING" });
public static readonly ReadOnlyCollection<string> ClerkDepartments
{ get { return clerkDepartments; } }
Note that although ReadOnlyCollection<T> isn't a totally immutable collection, only code with access to the underlying collection could change it - and as the only code which "knows" about the array is the initializer which passes it to the constructor, you're basically safe unless someone cracks out reflection :)
Perhaps use a ReadOnlyCollection?
http://msdn.microsoft.com/en-us/library/ms132474.aspx

constant string Alternative working with helper classes

When working with switch case, for example
I could use
const string FirstFloor = "lvl1", SecondFloor = "lvl2", ThirdFloor = "lvl3";
string ElavaetTo= "lvl1";
switch(ElavaetTo)
{
case FirstFloor:
Response.Redirect(FirstFloor + "Page.aspx")
break;
case SecondFloor:
Response.Redirect(SecondFloor + "Page.aspx")
break;
case ThirdFloor:
Response.Redirect(ThirdFloor + "Page.aspx")
break;
}
Edited :
this is only an example of where constant string wil not work if placed in another class
this is not a function / method i am trying to correct so it will work.
thanks for your time, i am trying to base my methods , my approach...
This would work fine placed in the current or same class of the project but when all variables are stored outside this class instead of simply instantiating the class and methods only once :
fullClassName shrtNm = New fullClassName();
then you would like to call it as with
shrtNm.MethodName();
You need to go the 'Long way around' specially if not including the Namespace via using statement
and you would have to call it like:
string strnm = MyNameOfNameSpace.fullClassName.ConstantntStrName;
instead of:
string strnm = shrtNm.ConstantStrName;
Is there an alternative to using any type that will represent string values inside the IntelliSense in an easy way ?
I have tried to use
public enum Elavation
{
lvl1,
lvl2,
lvl3
}
but then you need to declare it as in the long example plus a .ToString()
Is there any alternative at all?
Instead of declaring the variables as 'const' have your tired declaring them as 'readonly' ?
This would enable you to simply instantiat the class only once :
fullClassName shrtNm = New FullClassName();
then you would like to call it as with
shrtNm.<VariableName>;
Guessing from the use case you enumerated, I doubt the difference between using const and readonly should matter...
as far as i could get (only because it was important for me to addapt an aproach )
i found an example in a codeProjec page about using strings and String-Enumerations
that lead me to use that aproach and then turn my calss into a static class
public static class Qs
{
public sealed class Act
{
//private Act();
public const string edit = "edit", add = "add", remove = "remove", replace = "replace";
}
public sealed class State
{
public const string addnewTableRow = "addnewTableRow", cancelInsert = "cancelInsert", loadpagefromlink="loadpagefromlink";
}
public sealed class Params
{
public const string state = "state";
public const string custID = "custID";
public const string recordID = "recordID";
}
}
using sealed class accessing it via its parent className.Itsname
e.g.
Qs.Act.edit
as edit would show in IntelliSense

Are Enum the right way to go here?

I'm not sure if I am abusing Enums here. Maybe this is not the best design approach.
I have a enum which declares the possible parameters to method which executes batch files.
public enum BatchFile
{
batch1,
batch2
}
I then have my method:
public void ExecuteBatch(BatchFile batchFile)
{
string batchFileName;
...
switch (batchFile)
{
case BatchFile.batch1:
batchFileName = "Batch1.bat";
break;
case BatchFile.batch2:
batchFileName = "Batch2.bat";
break;
default:
break;
}
...
ExecuteBatchFile(batchFileName);
}
So I was wondering if this is sound design.
Another option I was thinking was creating a Dictionary<> in the constructor like this:
Dictionary<BatchFile, String> batchFileName = new Dictionary<BatchFile, string>();
batchFileName.Add(BatchFile.batch1, "batch1.bat");
batchFileName.Add(BatchFile.batch2, "batch2.bat");
Then instead of using a switch statement I would just go:
public void ExecuteBatch(BatchFile batchFile)
{
ExecuteBatchFile(batchFileName[batchFile]);
}
I'm guessing the latter is the better approach.
I'd probably go for a design along these lines:
public interface IBatchFile
{
void Execute();
}
public class BatchFileType1 : IBatchFile
{
private string _filename;
public BatchFileType1(string filename)
{
_filename = filename;
}
...
public void Execute()
{
...
}
}
public class BatchFileType2 : IBatchFile
{
private string _filename;
public BatchFileType2(string filename)
{
_filename = filename;
}
...
public void Execute()
{
...
}
}
In fact, I'd extract any common functionality into a BatchFile base class
What if you suddenly need a third batch file? You have to modify your code, recompile your library and everybody who uses it, has to do the same.
Whenever I find myself writing magic strings that might change, I consider putting them into an extra configuration file, keeping the data out of the code.
I would personally use a static class of constants in this case:
public static class BatchFiles
{
public const string batch1 = "batch1.bat";
public const string batch2 = "batch2.bat";
}
If you want to use an enum then you may want to consider utilising attributes so you can store additional inforation (such as the file name) against the elements.
Here's some sample code to demonstrate how to declare the attributes:
using System;
public enum BatchFile
{
[BatchFile("Batch1.bat")]
batch1,
[BatchFile("Batch2.bat")]
batch2
}
public class BatchFileAttribute : Attribute
{
public string FileName;
public BatchFileAttribute(string fileName) { FileName = fileName; }
}
public class Test
{
public static string GetFileName(Enum enumConstant)
{
if (enumConstant == null)
return string.Empty;
System.Reflection.FieldInfo fi = enumConstant.GetType().GetField(enumConstant.ToString());
BatchFileAttribute[] aattr = ((BatchFileAttribute[])(fi.GetCustomAttributes(typeof(BatchFileAttribute), false)));
if (aattr.Length > 0)
return aattr[0].FileName;
else
return enumConstant.ToString();
}
}
To get the file name simply call:
string fileName = Test.GetFileName(BatchFile.batch1);
I think the latter approach is better because it separates out concerns. You have a method which is dedicated to associating the enum values with a physical path and a separate method for actually executing the result. The first attempt mixed these two approaches slightly.
However I think that using a switch statement to get the path is also a valid approach. Enums are in many ways meant to be switched upon.
Using enums is ok if you don't need to add new batch files without recompiling / redeploying your application... however I think most flexible approach is to define a list of key / filename pairs in your config.
To add a new batch file you just add it to the config file / restart / tell your user the key. You just need to handle unknown key / file not found exceptions.
Is it really necessary that ExecuteBatch works on limited number of possible file names only?
Why don't you just make it
public void ExecuteBatch(string batchFile)
{
ExecuteBatchFile(batchFile);
}
The problem with the latter case is if something passed an invalid value that is not inside the dictionary. The default inside the switch statement provides an easy way out.
But...if you're enum is going to have a lot of entries. Dictionary might be a better way to go.
Either way, I'd recommend some way to provide protection of the input value from causing a bad error even in ammoQ's answer.
The second approach is better, because it links the batch file objects (enums) with the strings..
But talking about design, it would not be very good to keep the enum and the dictionary separate; you could consider this as an alternative:
public class BatchFile {
private batchFileName;
private BatchFile(String filename) {
this.batchFileName = filename;
}
public const static BatchFile batch1 = new BatchFile("file1");
public const static BatchFile batch2 = new BatchFile("file2");
public String getFileName() { return batchFileName; }
}
You can choose to keep the constructor private, or make it public.
Cheers,
jrh.
The first solution (the switch) is simple and straight forward, and you really don't have to make it more complicated than that.
An alternative to using an enum could be to use properties that returns instances of a class with the relevant data set. This is quite expandable; if you later on need the Execute method to work differently for some batches, you can just let a property return a subclass with a different implementation and it's still called in the same way.
public class BatchFile {
private string _fileName;
private BatchFile(string fileName) {
_fileName = fileName;
}
public BatchFile Batch1 { get { return new BatchFile("Batch1.bat"); } }
public BatchFile Batch2 { get { return new BatchFile("Batch2.bat"); } }
public virtual void Execute() {
ExecuteBatchFile(_fileName);
}
}
Usage:
BatchFile.Batch1.Execute();

Categories