C# Constantly renewing variable - c#

Hello I have a lot of variables as I mentioned below, but when I change the value of a variable that I refer to, this change is not adapted by the variables that use this variable.
class PublicVariable
{
public static string ActiveUser = UserInfo.Username;
public static string ActiveUserPath = $#"{Application.StartupPath}\{ActiveUser}";
public static string ActiveUserImg = $#"{ActiveUserPath}\User.png";
}
class UserInfo
{
public static string Username = "-1064548"; //Working
}
class Starting
{
public void Login(string Username, string Pwd)
{
//After the user logged in.
UserInfo.Username = "BruceWayne"; //Working
/* Showing -1064548 = */ MessageBox.Show(PublicVariable.ActiveUser.ToString()); //Not Working.
}
}
For simplicity of the code, ActiveUser is an example.
This code sequence is an example. The goal is to take the data from the database once.

To solve your problem I'd suggest to use properties here. This would look like this then:
class PublicVariable
{
public static string ActiveUser => UserInfo.Username;
public static string ActiveUserPath => $#"{Application.StartupPath}\{ActiveUser}";
public static string ActiveUserImg => $#"{ActiveUserPath}\User.png";
}
class UserInfo
{
public static string Username = "-1064548"; //Working
}
class Starting
{
public void Login (string Username, string Pwd)
{
UserInfo.Username = "BruceWayne";
MessageBox.Show (PublicVariable.ActiveUser.ToString ());
}
}
Alternatively you could use methods as well:
class PublicVariable
{
public static string ActiveUser() => UserInfo.Username;
public static string ActiveUserPath() => $#"{Application.StartupPath}\{ActiveUser()}";
public static string ActiveUserImg() => $#"{ActiveUserPath()}\User.png";
}
class UserInfo
{
public static string Username = "-1064548"; //Working
}
class Starting
{
public void Login (string Username, string Pwd)
{
UserInfo.Username = "BruceWayne";
MessageBox.Show (PublicVariable.ActiveUser().ToString ());
}
}
There actually isn't any major difference between properties and methods. However, fields (you used them) are different, as they don't update their value when the depending value changes. That means, as long as you don't have a reference to the other value (which would be the case for objects, like an object of your class Starting), the field value doesn't update.

Related

Add dynamic error message to custom regular expression

I have built a custom regular expression class. I also have a database value that is a list of characters that I don't want to be allowed anywhere in my web application. My custom regular expression class will take all other regular expressions and ensure that my list of unwanted characters are not allowed. My custom regular expression class is register in my Global.asax.cs and since it is a value in the database it can be changed when deemed necessary. Now what I need to do is find a way to take the regex error message and add on to it with something like: "This field cannot contain the following: " + mybadcharacterlist;
Already tried this:
public const string AlphaErrMsg = "This field can only contain letters. This field cannot include the following characters: " + RestrictedCharacterList.GetList();
Which didn't work because the error parameter for RegularExpressionAttribute requires a const and calling my GetList method isn't a constant.
protected void Application_Start()
{
DataAnnotationsModelValidatorProvider.RegisterAdapter(typeof (RestrictCharRegExpressAttribute), typeof(RegulatExpressionAttributeAdapter);
}
public class RestrictCharRegExpressAttribute : RegularExpressionAttribute
{
public RestrictCharRegExpressAttribute(string propRegex) : base(GetRegex(propRegex)) {}
private static string GetRegex(string propRegex)
{
in indexPropRegex = propRegex.IndexOf('^');
string restrictedCharsAction = "(?!.*[" + RestrictedCharacterList.GetList() + "])";
propRegex = indexPropRegex == -1 ? propRegex.Insert(0, restrictedCharsAction) : propRegex.Insert(indexPropRegex + 1, restrictedCharsAction);
return propRegex;
}
}
public static class RestrictedCharacterList
{
public static string GetList()
{
string restrictedChars;
if (HttpContext.Current?.Session == null)
{
restrictedChars = EnvironmentSettingsDA.GetSetting(AppConfiguration.Settings.ConnectionString, "CAMPS", "RESTRICTED_CHARACTERS");
}
else
{
restrictedChars = HttpContext.Current.Session.GetDataFromSession<string>("RESTRICTED_CHARACTERS");
if (restrictedChars == null)
{
restrictedChars = EnvironmentSettingsDA.GetSetting(AppConfiguration.Settings.ConnectionString, "CAMPS", "RESTRICTED_CHARACTERS");
HttpContext.Current.Session.SetDataToSession<string>("Restricted_Characters", restrictedChars);
}
}
return restrictedChars;
}
}
public class User
{
public const string IsAlphaRegex = "^[a-zA-Z]*$'
public const string AlphaErrMsg = "This field can only contain letters.";
[RestrictCharRegExpress(IsAlphaRegex, ErrorMessage = AlphaErrMsg)]
public string FirstName { get; set; }
}
The expected results would be to add a message to all my regex error messages describing what characters are not allowed while ensuring that list of characters can be changed in the database.
The way you do this is to override FormatErrorMessage in RestrictCharRegExprAttribute:
public class RestrictCharRegExprAttribute: RegularExpressionAttribute
{
public RestrictCharRegExpressAttribute(string propRegex): base( GetRegex(propRegex)
{
this.Message = ...; // localized message
}
private string Message { get; }
public override string FormatErrorMessage(string propertyName)
{
return this.Message;
}
}
Special thanks to Reviews Alot for leading me down the right path but this is what I did to accomplish what I was trying to do.
Added the following to RestrictedCharacterList class:
public static class RestrictedCharacterList
{
public static string GetErrorMessage()
{
return " Valid values cannot include the following restricted characters: " + GetList();
}
}
Added the following to RestrictCharRegExpressAttribute class:
public class RestrictCharRegExpressAttribute : RegularExpressionAttribute
{
public string AddToRestrictCharErrorMessage { get; set; }
public override string FormatErrorMessage(string name)
{
if (string.isNullOrWhiteSpace(AddToRestrictedCharErrorMessage))
{
return base.FormatErrorMessage(name);
}
else
{
return AddToRestrctCharErrorMessage + " " + RestrictedCharacterList.GetErrorMessage():
}
}
}
And then when you want the special character message appended to an existing error message you assign the data attribute like so:
public class User
{
public const string IsAlphaRegex = "^[a-zA-Z]*$'
public const string AlphaErrMsg = "This field can only contain letters.";
[RestrictCharRegExpress(IsAlphaRegex, AddToRestrictCharErrorMessage = AlphaErrMsg)]
public string FirstName { get; set; }
}

Passing a variable from a public class to a public static class

I have a public class and need to use one of those variables inside a public static class. Is this possible? If so: how can I call it?
public class xmlData
{
public string testing;
}
public static class fileUpload
{
public static string uploadFile(string file)
// I want to use the testing here
}
You would inject an instance of the xmlData into the method. Like this:
public static string uploadFile(xmlData data, string file)
Now inside that method you can do this:
data.testing ...
To access instance field from static method is not possible. You can pass value as parameter:
public static string uploadFile(string file, string testing)
Or pass object into method:
public static string uploadFile(string file, xmlData data)
{ string testing = data.testing; }
of course it's possible. you just pass it in.
string myString = fileUpload.uploadFile(testing);
All of the methods I can think of in one single spot:
public class xmlData
{
public string testing;
// part of "first option"
public void RunStatic() {
fileUpload.uploadFile(testing);
}
}
public static class fileUpload
{
// used by "option 1, 3"
public static string uploadFile(string testing) {
var firstOption = testing;
}
// used by "option 2"
public static string uploadFile(xmlData myObject, string file) {
var secondOption = myObject.testing;
}
}
public class Program {
public static void Main() {
var objectExample = new xmlData();
// first example
objectExample.RunStatic();
// second example
fileUpload.uploadFile(objectExample, "");
// third example
fileUpload.uploadFile(objectExample.testing);
}
}
All of these will work and should hopefully answer the question. A different question might be whether or not its a good idea to expose instance variables directly or should a property be used. Hm.

How to "send" a method to inside another method?

I have the following:
public class Mail {
public String Obfuscate(String email) {
return email.Replace("#", "at").Replace(".", "dot");
}
}
I am calling the method Obfuscate in a class, as follows:
public class Resolver {
public Data GetData () {
return new Data { Email = new Mail().Obfuscate(myEmail) };
}
public String Translate(string value) { /* Some Code */ }
}
The problem is that Obfuscate does the replacement in English: # > at, . > dot
But in the Resolver class the method Translate does exactly what I need ...
How can I "pass" the Translate method to the Obfuscate method so this one uses it to translate # and . to at and dot in the current language?
So the code line inside Obfuscate:
return email.Replace("#", "at").Replace(".", "dot");
Would be become:
return email.Replace("#", Translate("#")).Replace(".", Translate("."));
Where Translate would be the method that I am "passing" to it.
Than You,
Miguel
Consider a different design:
public interface ITranslator
{
string Translate(string s);
}
public class Obfuscator
{
public Obfuscator(ITranslator translator)
{
this.translator = translator;
}
public string Obfuscate(string email)
{
var at = translator.Translate("at");
var dot = translator.Translate("dot");
return email.Replace("#", at).Replace(".", dot);
}
private ITranslator translator;
}
public class EnglishTranslator : ITranslator
{
public string Translate(string s)
{
return s;
}
}
public class PolishTranslator : ITranslator
{
public PolishTranslator() //or `FileInfo dictionaryFile` parameter perhaps
{
// for simplicity
translations = new Dictionary<string, string>();
translations.Add("at", "malpa");
translations.Add("dot", "kropka");
}
public string Translate(string s)
{
return translations[s];
}
private Dictionary<string, string> translations;
}
However you really should consider using a ResourceManager. Resource related mechanisms are designed to deal with translations.
I think #BartoszKP's answer is the right design decision. For completeness, here's how to do what you asked.
Change Mail to take a Func<string,string>:
public class Mail {
public String Obfuscate(String email, Func<string,string> translate) {
return email.Replace("#", translate("at")).Replace(".", translate("dot"));
}
}
And pass your Translate method to it:
public class Resolver {
public Data GetData () {
return new Data { Email = new Mail().Obfuscate(myEmail, Translate) };
}
public String Translate(string value) { /* Some Code */ }
}

How to use multiple sets in class property when dealing with methods with multiple parameters?

I have a class that contains the following method (The Class name is ZipLoad):
private string DOit(string uName, string pWord)
{
DOSTUFF.....
return "Successfull";
}
Now I want pass parameters to the class using my program but there are two parameters. If there was one parameter i would simply do this:
private string testUser;
public string getSetUser
{
get { return testUser; }
set { testUser= DOit(value); }
}
And then use my Windows Forms Application to pass the parameters.
ZipLoad myZipLoad = new ZipLoad();
string report;
myZipLoad.testUser = "userName";
report= myZipLoad.getSetUser;
My Question is that how do I pass parameters to the DOit method using public properties in the class. One way is to make the method public but for some reason people say that is bad.
Any help would be appreciated ...
Thank You
maybe i'm wrong but set { testUser= DOit(value); } doesn't looks very useful what you are trying because if you get this to work and you are doing
myZipLoad.testUser = "userName";
report= myZipLoad.getSetUser;
string user = myZipLoad.testUser; //<- user == "Successfull"
so i build you this construct
class Program
{
static void Main(string[] args)
{
ZipLoad myZipLoad = new ZipLoad();
string report;
myZipLoad.TestUser = "userName";
report = myZipLoad.Stat; //<- modified
}
}
class ZipLoad
{
#region private Values
private string testUser;
private string pWord;
#endregion
#region Properties
public string TestUser
{
get { return testUser; }
set { testUser = value; }
}
public string PWord
{
private get { return pWord; }
set { pWord = value; }
}
// ADDED
public string Stat
{
get { return DOit_aka_Login(testUser, pWord); }
}
#endregion
private string DOit_aka_Login(string uName, string pWord) //<- modified
{
// now you may need to check the input if(uName =="" && pWord==""){...}
//DOSTUFF.....
return "Successfull";
}
}
if it doesn't fit your needs please add more information's

Using strings from other classes C#

I have a class that requests that when called a string is sent when requesting / initializing it.
class Checks
{
public Checks(string hostname2)
{
// logic here when class loads
}
public void Testing()
{
MessageBox.Show(hostname2);
}
}
How would it be possible to take the string "hostname2") in the class constructor and allow this string to be called anywhere in the "Checks" class?
E.g. I call Checks(hostname2) from the Form1 class, now when the Checks class is initialized I can then use the hostname2 string in my Checks class as well
Declare a member inside the class and assign the value you passed to the member inside the constructor:
class Checks
{
private string hostname2;
public Checks(string hostname2)
{
this.hostname2 = hostname2; // assign to member
}
public void Testing()
{
MessageBox.Show(hostname2);
}
}
If you also need to have outside access, make it a property:
class Checks
{
public string Hostname2 { get; set; }
public Checks(string hostname2)
{
this.Hostname2 = hostname2; // assign to property
}
public void Testing()
{
MessageBox.Show(Hostname2);
}
}
Properties start with a capital letter by convention. Now you can access it like this:
Checks c = new Checks("hello");
string h = c.Hostname2; // h = "hello"
Thanks to Andy for pointing this out: if you want the property to be read-only, make the setter private:
public string Hostname2 { get; private set; }
You need to copy the constructor argument in a class variable:
class Checks {
// this string, declared in the class body but outside
// methods, is a class variable, and can be accessed by
// any class method.
string _hostname2;
public Checks(string hostname2) {
_hostname2 = hostname2;
}
public void Testing() {
MessageBox.Show(_hostname2);
}
}
You can expose a public property to retun the hostname2 value which is the standard for exposing your private varibles
class Checks
{
private string _hostname;
public Checks(string hostname2)
{
_hostname = hostname2;
}
public string Hostname
{
get { return _hostname; }
}
}

Categories