Is there any way to make the input global? - c#

I want to use textBox1.Text in a different class not just in the main where the text boxes are defined so to say. Is there any way to make it global? Because it only allows me to use it in the main thing, not in the seperate class that I have to make in my task.
I need to store the text from the textBox in a List that is in a different class so the user can't add the same name twice so I need to remember what was typed in in the first input.
This is the class where I created a List and where I want to store those inputs:
internal class Clanovi
{
public static List<Clan> Dodaj()
{
List<Clan> clanovi = new List<Clan>();
clanovi.Add(new Clan() { KorIme = textBox1.Text, Lozinka = textBox2.Text });
return clanovi;
}
}
class Clan
{
public string KorIme { get; set; }
public string Lozinka { get; set; }
}
This is WinForm btw.

Your variable names are in another language so it is hard to understand but I think you want this
internal class Clanovi
{
public static List<Clan> Dodaj()
{
Global.clanovi.Add(new Clan() { KorIme = textBox1.Text, Lozinka = textBox2.Text });
// you don't need to return this since it is already global
return clanovi;
}
}
public static class Global
{
public static List<Clan> clanovi = new List<Clan>();
}
public static class Clan
{
public static string KorIme { get; set; }
public static string Lozinka { get; set; }
}
Whenever you want to access your global variables, you use the Global class with the static items in it.

i suggest to:
change the modifiers property in the properties of the textbox to public.
write this code in the other class :
Form_name/class_name myTextbox = new form_name/class_name();
ex:
Form1 myTextbox = new Form1();
now u can use in any other class/form: mytextbox.Textbox.text.
internal class Clanovi
{
Clan myTextbox = new Clan();
public static List<Clan> Dodaj()
{
List<Clan> clanovi = new List<Clan>();
clanovi.Add(new Clan() { KorIme = myTextbox.textBox1.Text, Lozinka = textBox2.Text });
return clanovi;
}
}

Related

C# Is there a way to make the properties of an object in a class non-editable outside the class itself?

I am looking for a way to have an object in a class and make it non-editable (the object itself AND its properties) outside the class itself but still visible outside.
internal class Room
{
public string Description { get; set; }
}
internal class RoomController
{
public Room Room { get; private set; }
public RoomController()
{
Room = new Room();
}
//Edit the room inside this class
}
internal class Foo
{
public void SomeMethod()
{
RoomController rc = new RoomController();
rc.Room.Description = "something"; // This should not be allowed
string roomDesc = rc.Room.Description; // This should be fine
}
}
Is something like that possible? I couldn't find anything regarding the issue so I would be grateful if anyone has any ideas.
Thanks in advance!
You could define an interface that only exposes the bits you want public:
internal interface IReadonlyRoom
{
string Description { get; } //note only getter exposed
}
internal class Room : IReadonlyRoom
{
public string Description { get; set; }
}
internal class RoomController
{
private Room _room;
public IReadonlyRoom Room => _room;
public RoomController()
{
_room = new Room();
}
//edit using _room
}

Don't allow object to be changed

I have a read-only object but somewhere it's properties getting updated. Does C# have anything to restrict that too from direct changes as well as via reflection?
Here is the POC code
class Program
{
static void Main(string[] args)
{
ReadOnlyCreator tester = new ReadOnlyCreator();
tester.ModifyTester();
Console.ReadLine();
}
}
class ClassUnderTest
{
public string SomeProp { get; set; }
}
class ReadOnlyCreator
{
private readonly ClassUnderTest _classUnderTest;
public ReadOnlyCreator()
{
_classUnderTest = new ClassUnderTest { SomeProp = "Init" };
}
public void ModifyTester()
{
Console.WriteLine("Before: " + _classUnderTest.SomeProp);
var modifier = new Modifier(_classUnderTest);
modifier.Modify();
Console.WriteLine("After: " + _classUnderTest.SomeProp);
}
}
class Modifier
{
private ClassUnderTest _classUnderTest;
public Modifier(ClassUnderTest classUnderTest)
{
_classUnderTest = classUnderTest;
}
public void Modify()
{
_classUnderTest.SomeProp = "Modified";
}
If you want a read only object you should make it read only. i.e.
class ClassUnderTest
{
public string SomeProp { get; }
public ClassUnderTest(string someProp) => SomeProp = someProp;
}
You could also use init only setters if you are using c#9. This allow the property to be set only during construction of the object:
class ClassUnderTest
{
public string SomeProp { get; init; }
}
If you are using value types you can (and should) declare the whole type as readonly. See also Choosing Between Class and Struct
public readonly struct StructUnderTest
This does not protect against reflection or unsafe code. Using these features is deliberately circumventing the rules, so it is up to the developer to ensure it is safe.

Get property default value on class initialize

Let's say we have some class CarsBase
public class CarsBase
{
public string DisplayName { get; set; }
}
Then we have some other class Toyota
public class Toyota : CarsBase
{
public EngineType EngineType { get; set; }
}
Then we are initializing our class instance by using object initializer like so:
var myVar = new Toyota()
{
// DisplayName = "", ← We could do this by our hands, but can it be done automatically?
EngineType = EngineType.UZ
}
Question: Is there any way to fill CarsBase's DisplayName property automatically on object initialize?
Like, if I had several more car classes (BMW, Suzuki , etc.), each is extending CarsBase and as a result have DisplayName property in each class.
This sounds like something that should be done in a constructor.
public class Toyota : CarsBase
{
public Toyota() : base()
{
base.DisplayName = "Toyota";
}
public EngineType EngineType { get; set; }
}
Another option, however less recommended, instead of getting/setting a DisplayName in the same sense, the base class could be changed to use reflection retrieve the classname and use that as the display name:
public class CarsBase
{
public string DisplayName
{
get
{
return this.GetType().Name;
}
}
}
This method should just return the "Toyota" from the classname, however would prevent usage of spaces or other special characters. Reflected code such as this also has a tendency to be slower.
Create a constructor to pass dispay name (or other parameters as required)-
Toyota(string displayName)
{
DisplayName = displayName;
EngineType = EngineType.UZ;
}
Then you can call like this-
new Toyota("some display name");
Just set the property value in the constructor. Something like this:
internal class Program
{
private static void Main(string[] args)
{
Toyota t = new Toyota() { EngineType = new EngineType() };
Console.WriteLine(t.DisplayName);
Console.ReadLine();
}
}
public class CarsBase
{
public string DisplayName { get; set; }
}
public class Toyota : CarsBase
{
public EngineType EngineType { get; set; }
public Toyota()
{
// set the default Display Name
// that way you don't have to set it everytime
this.DisplayName = "Oh what a feeling!";
}
}
public class EngineType { }
Yes, it can be done during the initialization stage of object where constructor is fired . I have created two classes
* one for holding enum constant value for engine_Types --> EngineType
one for explaining the inheritance,Constructor-Chaining, creating an instance of class which is an object----> CarsBase
[pre]
namespace stacketst
{
public class CarsBase
{
public string DisplayName { get; set; }
public CarsBase()
{
//called when CarBase object is initialized
DisplayName = "Base Car";
}
}
public class Toyota : CarsBase
{
//getters , setters called as properties in C#
public int number_of_wheels { get; set; }
public double fuel_capacity { get; set; }
public string engine_type { get; set; }
public Toyota() //called when an instance of Toyota is created
{
//assinging value to this property calls set
fuel_capacity = 4.2;
number_of_wheels = 4;
engine_type = EngineType.name_engines.UZ.ToString();
}
}
public class TestClass
{
static void Main()
{
//when below line is executed,constructor is fired & the initialization of variable inside constructor takes place
var myVar = new Toyota();
Console.WriteLine(myVar.DisplayName);
}
}
}
namespace stacketst
{
public class EngineType
{
//enums to hold constants, common for any Car Class
public enum name_engines
{
V12, V10, V8, V6, UZ
};
}
}
[/pre]

How to access one class from two windows (C# WPF)

I've got two windows(MainWindow,SecondWindow), one class (ExampleClass) in ExampleClass two strings (Name,SecondName) and method with messagebox which should contains text from Name + SecondName variables.
So i want to add some text from MainWindow to ExampleClass Name string and then some text from opened SecondWindow to ExampleClass SecondName string. After that i want to click on MainWindow button and that should give me messagebox with both of strings
Name + SecondName
MainWindow :
ExampleClass SomeClass = new ExampleClass();
SomeClass.Name = MainWindowTxtBox.Text;
Second Window :
ExampleClass SomeClass = new ExampleClass();
SomeClass.SecondName = SecondWindowTxtBox.Text;
This will create new istance of class only for one window, is it possible to create istance for both Windows?
You can use static like this:
class ExampleClass
{
public static string Name { get; set; }
public static string SecondName { get; set; }
public static void print()
{
MessageBox.Show(Name + SecondName);
}
}
Then in MainWindow:
ExampleClass.Name = MainWindowTxtBox.Text;
And in the SecondWindow:
ExampleClass.SecondName = SecondWindowTxtBox.Text;
And finally:
ExampleClass.print();
Yes this is possible. But one class needs to know the other class. Try it like this:
Class1
{
public ExampleInstance Instance { get; set; }
//Create your Class2 object here with Class2 SecondClassObject = new Class2(this)
}
Class2
{
private Class1 MyCreator;
public Class2(Class1 Creator)
{
this.MyCreator = Creator;
}
//Now you can use the object with: MyCreator.Instance
}
Hope this helps.
You should then create the instances of your class in the main application instead of the windows.
Create a singleton (https://msdn.microsoft.com/en-us/library/ff650316.aspx):
public class ExampleClass
{
public string Name { get; set; }
public string SecondName { get; set; }
protected ExampleClass() {
}
static ExampleClass _instance;
public static ExampleClass Instance {
get {
return _instance ?? (_instance = new ExampleClass());
}
}
}
and your code will look like this:
MainWindow
ExampleClass.Instance.Name = MainWindowTxtBox.Text;
Second Window
ExampleClass.Instance.SecondName = SecondWindowTxtBox.Text;

C# nested class/struct visibility

I'm trying to figure out what the proper syntax is to achieve a certain API goal, however I am struggling with visibility.
I want to be able to access a Messenger instance's member like msgr.Title.ForSuccesses.
However, I do not want to be able to instantiate Messenger.Titles from outside my Messenger class.
I'm also open to making Messenger.Titles a struct.
I'm guessing I need some sort of factory pattern or something, but I really have no idea how I'd go about doing that.
See below:
class Program {
static void Main(string[] args) {
var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this should be allowed
var t = new Messenger.Titles(); // this should NOT be allowed
}
}
public class Messenger {
// I've tried making this private/protected/internal...
public class Titles {
public string ForSuccesses { get; set; }
public string ForNotifications { get; set; }
public string ForWarnings { get; set; }
public string ForErrors { get; set; }
// I've tried making this private/protected/internal as well...
public Titles() {}
}
public Titles Title { get; private set; }
public Messenger() {
Title = new Titles();
}
}
You just need to make Titles private and expose an interface instead of it.
class Program {
static void Main(string[] args) {
var m = new Messenger { Title = { ForErrors = "An unexpected error occurred ..." } }; // this is allowed
var t = new Messenger.Titles(); // this is NOT allowed
}
}
public class Messenger {
public interface ITitles {
string ForSuccesses { get; set; }
string ForNotifications { get; set; }
string ForWarnings { get; set; }
string ForErrors { get; set; }
}
private class Titles : ITitles {
public string ForSuccesses { get; set; }
public string ForNotifications { get; set; }
public string ForWarnings { get; set; }
public string ForErrors { get; set; }
}
public ITitles Title { get; private set; }
public Messenger() {
Title = new Titles();
}
}
If you make the Titles constructor internal you will be able to create instances of it within your assembly only. If it is an API, perhaps that will be protected enough? You can see this pattern within the BCL (such as HttpWebRequest that can be created only through calls to WebRequest.Create).
Why Would I Ever Need to Use C# Nested Classes Nested type is never intended to be initialized from external type.
Well, you could make Titles a struct and make the constructor either public or internal. In that way, every time a client gets a copy of the Titles instance through the Title property, they will be getting the value, not the reference. They could modify that value, but to apply that change to the internal state of your object, they would need to be able to set the value back again through the Title property. They can't, because you have the Title setter marked private.
You will have to do the same when you change a value internally. For example:
// Your constructor...
public Messenger()
{
Titles t = new Titles();
t.ForSuccesses = "blah";
Title = t;
}
You can do this internally because you have access to the private setter for the Title property.
The main downside is that it might confuse the clients of your framework a bit because it looks like you can set the values of the Titles instance, but there is no real way for them to commit that change back to the Messenger class.

Categories

Resources