I am trying to print two methods that i have created but i cant figure out how to do it.
My project consists of Language.cs file in addition to Program.cs
This method in Language.cs:
public static void PrettyPrintAll(IEnumerable<Language> langs)
{
foreach (var printsAll in langs)
{
Console.WriteLine(printsAll.Prettify());
}
}
Prints out this method that is also in Language.cs:
public string Prettify()
{
return $"{Year}, {Name}, {ChiefDeveloper}, {Predecessors}";
}
this method prints out every query result (is also in Language.cs):
public static void PrintAll(IEnumerable<Object> sequence)
{
foreach (var prints in sequence)
{
Console.WriteLine(prints);
}
}
Language class code other than the methods above:
namespace ProgrammingLanguages
{
public class Language
{
public static Language FromTsv(string tsvLine)
{
string[] values = tsvLine.Split('\t');
Language lang = new Language(
Convert.ToInt32(values[0]),
Convert.ToString(values[1]),
Convert.ToString(values[2]),
Convert.ToString(values[3]));
return lang;
}
public int Year
{ get; set; }
public string Name
{ get; set; }
public string ChiefDeveloper
{ get; set; }
public string Predecessors
{ get; set; }
public Language(int year, string name, string chiefDeveloper, string predecessors)
{
Year = year;
Name = name;
ChiefDeveloper = chiefDeveloper;
Predecessors = predecessors;
}
All the methods are within the Language.cs file.
My issue is that i do not understand how to print them, i have tried in many ways but always get an error code The name 'PrintAll' does not exist in the current context or something like that.
In main this is how i have tried to call the method PrintAll:
var stringLanguage = languages.Select(languagePrint => $"{languagePrint.Year}
{languagePrint.Name} {languagePrint.ChiefDeveloper}");
PrintAll(stringLanguage);
The static method PrintAll() belongs to the class Language and calling it from another class requier to prepend the class name first, such as Language.PrintAll()
public static void Main()
{
// some code ...
var stringLanguage = languages.Select(languagePrint => $"{languagePrint.Year} {languagePrint.Name} {languagePrint.ChiefDeveloper}");
// PrintAll(stringLanguage); <-- This won't work because there is no method PrintAll() in the current class
// This now refers to the correct class where the method belongs
Language.PrintAll(stringLanguage);
}
Another way to do that would be to include the static part of the class Language in the class where Main is (I assume the class Program) :
// replace namespace by the correct namespace of the class
using static namespace.Language;
class Program
{
public static void Main()
{
// some code ...
var stringLanguage = languages.Select(languagePrint => $"{languagePrint.Year} {languagePrint.Name} {languagePrint.ChiefDeveloper}");
// This now works because the static parts were imported
PrintAll(stringLanguage);
}
}
However, I discourage using this, because this may lead to confusion
public class Program
{
public static void Main(string[] args)
{
var c = check.myValue("Example 1"); //This is the pattern I've to use, don't want to create an object (Is it possible to use it with static class)
Console.WriteLine(c.result1);
Console.WriteLine(c.result2);
}
}
public static class check
{
public static void myValue(string qr)
{
public string result1 = "My Name" + qr;
public string result1 = "You're" + qr;
}
}
See here Online Example (Code is not working)
Every thing on main function I've to use exactly the same pattern because I'll use it in a lot of different classes and I don't want to create object each and every time by using non-static class.
Please correct me if I'm wrong
There's a lot wrong with the syntax of that code, which #Sergey addresses in his answer.
You appear to want to return an instance of a class from a static method, and that class should contain two properties.
You can do that by creating the actual, nonstatic class containing the properties:
public class Check
{
public string Result1 { get; set; }
public string Result2 { get; set; }
}
Then return a new instance from the static method therein:
public static Check MyValue(string qr)
{
var result = new Check();
result.Result1 = "My Name" + qr;
result.Result2 = "You're" + qr;
return result;
}
However, you're saying in the comments in your code that you don't want to use an object.
In that case it appears you want to use static properties. That's generally not recommendable, but it would look like this:
public static class Check
{
public static string Result1 { get; set; }
public static string Result2 { get; set; }
public static void MyValue(string qr)
{
Result1 = "My Name" + qr;
Result2 = "You're" + qr;
}
}
Then you can read Check.Result1 after calling the method MyValue().
Your code is totally wrong
myValue method returns void. You cannot assign void return value to variable.
You cannot have public modifiers for local variables.
You cannot have local variables with same name in same scope
If you want to return two values from method, then you should return object with two fields - custom class or tuple. You can also use out parameters, but I don't think it's your case
public static class Check
{
public static Tuple<string, string> MyValue(string qr)
{
return Tuple.Create($"My Name {qr}", $"You're {qr}");
}
}
With C# 7 it's a little bit better. You can write this method in one line and provide names for tuple properties
(string MyName, string YourName) MyValue(string qr) => ($"My Name {qr}", $"You're {qr}");
Usage
var result = Check.MyValue("Example 1");
Console.WriteLine(result.Item1); // result.MyName
Console.WriteLine(result.Item2); // result.YourName
You can practice with creating custom class with nicely named properties instead of using tuples.
Does C# have such a feature (like Python's getter-only pattern)?
class A
{
public [read-only] Int32 A_;
public A()
{
this.A_ = new Int32();
}
public A method1(Int32 param1)
{
this.A_ = param1;
return this;
}
}
class B
{
public B()
{
A inst = new A().method1(123);
Int32 number = A.A_; // okay
A.A_ = 456; // should throw a compiler exception
}
}
To obtain this I could use the private modifier on the A_ property, and only implement a getter method. Doing so, in order to access that property I should always make a call to the getter method... is it avoidable?
Yes that is possible, syntax is like this:
public int AProperty { get; private set; }
yes. you can use read only property with private setter.
Using Properties - msdn
public string Name
{
get;
private set;
}
i have one main class and with in this main class i have another class A. class A has few static property and when i tried to access those static property from outside but getting error....not being possible
here is my classes structure
public class EShip
{
class Credentials
{
private static string _accessKey = "aaa";
private static string _accessPwd = "xxx";
private static string _accountNumber = "2222";
public static string AccessKey
{
get { return _accessKey; }
}
public static string AccessPassword
{
get { return _accessPwd; }
}
public static string AccountNumber
{
get { return _accountNumber; }
}
}
public static Credentials Credential
{
{ get; }
}
}
i try to expose that inner class by a main class property and from outside i try to do like
EShip.Credentials.AccessKey
EShip.Credentials.AccessPassword
it is not getting possible......suggest me good approach and why i am stuck. thnx.
Class Credentials is not public, therefore it's not accessible. Change that and you're able to do:
String key = EShip.Credentials.AccessKey;
Access Modifiers (C# Programming Guide)
Edit 1
Is it possible to do this with get/set? Something like the below? This works for me but I am worried I am missing something not to mention all the staticness.
///<summary>
/// Class to track and maintain Heads Up Display information
///</summary>
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
private static string _lastName;
private static string _firstName;
private static string _middleName;
private static string _suffix;
private static string _sSN;
private static string _personID;
private static string _masterID;
private static string _enrollmentID;
private static string _planID;
// Store a reference to THE form that holds the HUD and is visible
private static FrmModuleHost _frmHUDHost;
public static string PersonId
{
get { return _personID; }
set
{
FrmHudHost.tbxHUD_PersonID.Text = value;
_personID = value;
}
}
public static string SSn
{
get { return _sSN; }
set
{
FrmHudHost.tbxHUD_SSN.Text = value;
_sSN = value;
}
}
public static string MiddleName
{
get { return _middleName; }
set
{
FrmHudHost.tbxHUD_MiddleName.Text = value;
_middleName = value;
}
}
public static string FirstName
{
get { return _firstName; }
set
{
FrmHudHost.tbxHUD_FirstName.Text = value;
_firstName = value;
}
}
public static string LastName
{
get { return _lastName; }
set
{
FrmHudHost.tbxHUD_LastName.Text = value;
_lastName = value;
}
}
public static string Suffix
{
get { return _suffix; }
set
{
FrmHudHost.tbxHUD_SuffixName.Text = value;
_suffix = value;
}
}
public static string MasterID
{
get { return _masterID; }
set
{
FrmHudHost.tbxHUD_MasterID.Text = value;
_masterID = value;
}
}
public static string EnrollmentID
{
get { return _enrollmentID; }
set
{
FrmHudHost.tbxHUD_EnrollmontPeriod.Text = value;
_enrollmentID = value;
}
}
public static string PlanID
{
get { return _planID; }
set
{
FrmHudHost.tbxHUD_PlanID.Text = value;
_planID = value;
}
}
public static FrmModuleHost FrmHudHost
{
get { return _frmHUDHost; }
set { _frmHUDHost = value; }
}
}
Original Post
I have a class that is responsible for updating a Heads Up Display of current selected member info. My class looks like this -->
public static class HUD
{
///<summary>
///Declare variables to store HUD values
///</summary>
public static string _lastName;
public static string _firstName;
public static string _middleName;
public static string _suffix;
public static string _sSN;
public static string _personID;
public static string _masterID;
public static string _enrollmentPeriod;
public static string _planID;
///<summary>
/// Method to update the display with current information
///</summary>
public static void UpdateHUD (FrmModuleHost frm, params String[] args)
{
frm.tbxHUD_LastName.Text = args[0];
_lastName = args[0];
frm.tbxHUD_FirstName.Text = args[1];
_firstName = args[1];
frm.tbxHUD_MiddleName.Text = args[2];
_middleName = args[2];
frm.tbxHUD_SSN.Text = args[3];
_sSN = args[3];
frm.tbxHUD_PersonID.Text = args[4];
_personID = args[4];
}
}
What I am trying to figure out is how I can tell what args are being passed. What you see below is what is called from the Search Page as that is all that is available at that point. The other 4 values will be loaded 1 at a time on various pages. A person HAS A enrollment which HAS A plan if that helps.
private void GetResults()
{
var lName = getCurrentRowVal("Last Name");
var fName = getCurrentRowVal("First Name");
var pID = getCurrentRowVal("Person ID");
var sSN = getCurrentRowVal("SSN");
var mName = getCurrentRowVal("Middle Name");
HUD.UpdateHUD(FrmWwcModuleHost, lName, fName, mName, sSN, pID);
}
Now when I call this from the Enrollment Page I will want everything to stay and add the EnrollmentID.
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, enrollmentID);
}
My question is, How do I do that and know which arg[] index to call and not overwrite the existing values?
Is it as simple as always providing ALL parameters as they are set? So my call from the Enrollment Page would instead look like this -->
private void GetResults()
{
var enrollmentID = getCurrentRowVal("EnrollmentID");
HUD.UpdateHUD(FrmWwcModuleHost, HUD._lastName, HUD._firstName, HUD._middleName, HUD._sSN, HUD._personID, enrollmentID);
}
Thanks for any insights!
You'll really need to ditch the params style call and establish real parameters for your methods. Just create multiple overloads for your most common call signatures.
I did not see a reference to a particular version of .net you are using. Here is how I handle this in .net 3.5.
First create a class for passing the update values in, but make all of the properties nullable (since all of your items are string, they are already nullable). If the values are nullable, add actual property setters, and LastNameChanged properties.
public class UpdateData {
public string LastName { get; set;};
public string FirstName { get; set;};
public string MiddleName { get; set;};
...
}
Now your method signature looks like this:
public static void UpdateHUD (FrmModuleHost frm, UpdateData data)
{
if (!string.IsNullOrEmpty(data.FirstName) {
frm.tbxHUD_LastName.Text = data.FirstName;
_lastName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.LastName) {
frm.tbxHUD_FirstName.Text = data.LastName;
_firstName = data.FirstName;
}
if (!string.IsNullOrEmpty(data.MiddleName) {
frm.tbxHUD_MiddleName.Text = data.MiddleName;
_middleName = data.FirstName;
}
Next is the setting the UpdateData and calling the method:
UpdateHUD(FrmWwcModuleHost, new UpateData{ FirstName = "test1", LastName = "test2", ...});
Final note: you are using a lot of statics here. You might consider changing most of them. Move the static variables to an actual class with properties (but no statics), and reference the class in your code.
Perhaps instead of
params String[] args
you should do
params KeyValuePair<String,String>[] args
where any given param's properies would be assigned something like this:
Key = "Last Name"
Value = "Hare"
Then inside your UpdateHUD method you could check to see what the Key of the parameter was so you would know which value was being passed.
You could also create a separate class to pass in the params array. Something like:
public class HUDParam {
public HUDParam(paramName, paramValue) { /*[init code here...]*/ }
public string Name { get; set; }
public string Value { get; set; }
}
Then:
HUD.UpdateHUD(frm, new HUDParam("FirstName", "Tom"),
new HUDParam("LastName", "Thompson");
In your update method, you can just check the name and set the appropriate value in your HUD.
C# 4.0 has optional params which are much different from the params keyword. Params keyword is literally no different at runtime than if you didn't have the params keyword at all. In other words, you just get an array of values with no way of knowing which are which. Params keyword is just a C# convenience at compile time.
Although I haven't used C# 4.0 optional parameters yet, I imagine they behave similarly to the way VB.NET optional parameters did in that you can specify a default value at the function and that default will be used if the caller doesn't specify it. But the caller still has to indicate (either with missing values or paramName:= syntax) which parameter they are specifying.
In your case I think you're better off using either normal named parameters and passing null when you don't need them, or pass a dictionary/hashtable instead.
You could pass the arguments with a Dictionary where you can assign a value to a certain name.
The cleanest version would be to make a method for each variable.
e.g.
void UpdateLastName(string name)
{
frm.tbxHUD_LastName.Text = _lastName = name;
}
If you can use Framework 4.0, you can use optional and named parameters. Until that time, you will need to pass all the arguments.
But, I think by your question you might misunderstand what's happening slightly. The arguments you send in params are going into the method as an argument. Their scope therefore is the method itself, so you not "overwriting" anything. The array that you used for the first call is gone (out of scope) and the array you use for the second call will have whatever you put in it. Best way to do optional parameters before 4.0 is using multiple method overloads.
If you have a name association with a value but possibly unknown name values this is a candidate for a Dictionary .
Optional parameters involve no less checking than checking a dictionary if a key exists or if a member of a class is null. Since there already exists a primitive for this and it's more flexible I see no reason to use variable parameters or optional parameters.
What I would do is use an ananoymous type (which can be turned into a dictionary at runtime) and then changing the values which are present.
New function definition:
public static void UpdateHUD (FrmModuleHost frm, object args);
And client code:
UpdateHUD(frm, new {
MiddleName = "Jed",
SSN = "..." });
Using the code from Roy Osherove's Blog, this can be turned into a dictionary. The new implementation would be similar to:
var dictionary = MakeDictionary(args);
if ( dictionary.ContainsKey("SSN") ) { _sSN = dictionary["SSN"]; }
Of course, this will all be irrelevant when C# 4.0 comes out.