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; }
}
}
Related
Is there an access modifier, or combination thereof, to restrict access to an outer class only?
For the Position property of nested class PanelFragment below, I would like only the containing class ViewPagerPanels to be able to set it (via the setter, I realize this could be done through a constructor parameter also).
public class ParcelView : MXActivityView<ParcelVM>, ViewPager.IOnPageChangeListener, IFragmentToViewPagerEvent
{
private ViewPagerPanels _pagerPanels;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
_pagerPanels = new ViewPagerPanels(5); // 5: magic number, put int constant
_pagerPanels[0] = new ViewPagerPanels.PanelFragment(typeof(ViewA));
// ...
}
private class ViewPagerPanels
{
public class PanelFragment
{
public Fragment Fragment { get; set; }
// ?? - access modifer for set
public int Position { get; private set; }
}
public readonly int PANEL_COUNT;
private PanelFragment[] _panels;
public ViewPagerPanels(int count)
{
PANEL_COUNT = count;
_panels = new PanelFragment[PANEL_COUNT];
}
public PanelFragment this[int i]
{
get
{
return _panels[i];
}
set
{
_panels[i] = value;
// !! - cannot access private property
_panels[i].Position = i;
}
}
}
}
No, it's not possible to do it directly. The most restrictive access modifier, private, already allows access from within the same class. Every other modifier further expands that access.
Every class, no matter if its nested, private or public, always has access to every single of its own declared members, with no chance of applyng restrictions to itself. The closest we can get is by using a readonly field (or a getter only property) that prevents the declaring class from modifying a variable outside the constructor. But for a read-write one, we're out of options.
There is a solution for this type of protection scenarios. But you should do the following changes;
1- Replace you concrete class with an interface or abstract class and expose this to outside world
2- Implement this interface with a concrete class
3- Control the creation of this class by a factory method
4- Set the property by casting the interface (or abstract class) to your private class type
Sample code changes
public interface IPanelFragment
{
Fragment Fragment { get; set; }
// ?? - access modifer for set
int Position { get; }
}
class PanelFragment : IPanelFragment
{
public Fragment Fragment { get; set; }
// ?? - access modifer for set
public int Position { get; set; }
}
private IPanelFragment[] _panels;
public IPanelFragment CreateFragment(Fragment fragment, int pos)
{
return new PanelFragment() { Fragment= fragment, Position = pos };
}
public IPanelFragment this[int i]
{
get
{
return _panels[i];
}
set
{
_panels[i] = value;
// !! - cannot access private property
((PanelFragment)_panels[i]).Position = i;
}
}
A possible workaround
public int Position { get; private set; }
public int InitPosition { set { Position = value; } }
or, depending on your philosophical perspective concerning getter-less Properties
public void InitPosition(int value) { Position = value; }
I have 2 classes:
public class Access
{
public class Job
{
public int Id { get; set; }
protected string JobName { get; set; }
}
}
Class2.cs
public class Full: Access.Job
{
}
Full ful = new Full();
Why I'm not able to access the ful.JobName member?
Because You are trying to access protected method from outside the class. Only public methods are available. You can access the property/variably/method that is protected, only in the inherited class, but not from outer code:
public class Full: Access.Job
{
public void mVoid()
{
Console.WriteLine(this.JobName);
}
protected void mProtVoid()
{
Console.WriteLine(this.JobName);
}
private void mPrivateVoid()
{
Console.WriteLine("Hey");
}
}
Full myFull = new Full();
myFull.mVoid(); //will work
myFull.mProtVoid(); //Will not work
myFull.mPrivateVoid(); //Will not work
If You need to get to the protected property, there are 2 ways (3 actually, but Reflection is the dirty way and should be avoided):
1. Make it public
If it will be set to public, it will be stil inherit and You can directly access it:
Full nFull = new Full();
Console.Write(nFull.JobName);
2. Make a "wrapper"/"facade"
Create new property or method, that will just access the hidden property and return it in expected format.
public class Full: Access.Job
{
public string WrappedJobName { get { return this.JobName; } }
public string WrappedJobName => this.JobName; //C# 6.0 syntax
}
Full mFull = new Full();
Console.WriteLine(mFull.WrappedJobName);
I've declared a list in a class. I want to access the list from another class. How can I access the list from a module of another class?
// ClsUser.cs
namespace WebLll.ApiPayment.BusinessObject
{
public class ClsUser
{
Data.MyEntity db = new Data.MyEntity("MyEntity1");
public List<Data.GetPaymentRslt> BRIlstTxn = db.GetPayment(obj.PaymentCode, dtFrom, dtTo, obj.PaymentMode).ToList();
//... remaining code
}
}
// clsWebLllAPI.cs
namespace WebLll.ApiPayment.BusinessObject
{
public class clsWebLllAPI : clsBaseApi
{
public void Initialize(api_rule_setup obj)
{
// access the BRIlstTxn here
}
}
}
Since the list is public you can simply create an instance of the class and access it like follow,
ClsUser clsuser=new ClsUser();
List<Data.GetPaymentRslt> mylist=clsuser.BRIlstTxn; // Simply access PUBLIC field
From MSDN
Accessing a field in an object is done by adding a period after the object name
But as good programming practice,I suggest you to use Accessors over making a field public (need to know why, check this)
Suggestion code :
// ClsUser.cs
namespace WebLll.ApiPayment.BusinessObject
{
public class ClsUser
{
Data.MyEntity db = new Data.MyEntity("MyEntity1");
private List<Data.GetPaymentRslt> BRIlstTxn = db.GetPayment(obj.PaymentCode, dtFrom, dtTo, obj.PaymentMode).ToList();
// Only GET . Provide protection over setting it
public List<Data.GetPaymentRslt> brIlstTxn{
get
{
return BRIlstTxn;
}
}
//... remaining code
}
}
// clsWebLllAPI.cs
namespace WebLll.ApiPayment.BusinessObject
{
public class clsWebLllAPI : clsBaseApi
{
public void Initialize(api_rule_setup obj)
{
ClsUser clsuser=new ClsUser();
List<Data.GetPaymentRslt> mylist=clsuser.brIlstTxn; // Now you are accessing GET accesor rather than field directly
}
}
}
You can use Dot, member access operator to access public/internal/protected data member (list) of other class.
namespace WebLll.ApiPayment.BusinessObject
{
public class clsWebLllAPI : clsBaseApi
{
public void Initialize(api_rule_setup obj)
{
ClsUser clsUser = new ClsUser ();
var lst = clsUser.BRIlstTxn;
}
}
}
I have a static Class and within it I have multiple public static attributes. I treat this class as my global class.
However now I need to treat this class as a variable so that I can pass it to a method of another class for processing..
I can't instantiate this class.. So in effect I can only assign the variables inside this class.
Is my understanding correct or am I missing something?
public static class Global
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
Let say I have a class like this, and I need to somehow keep a copy of this in another class maybe
public static class Global_bk
{
public const int RobotMax = 2;
// GUI sync context
public static MainForm mainForm;
public static SynchronizationContext UIContext;
// Database
public static Database DB = null;
public static string localDBName = "local.db";
public static Database localDB = null;
public static Database ChangeLogDB = null;
public static string changeLogDBName = "ChangeLog.db";
}
I need to copy the contents from Global to Global_bk.
And after that I need to compare the contents of the two classes in a method like
static class extentions
{
public static List<Variance> DetailedCompare<T>(T val1, T val2)
{
List<Variance> variances = new List<Variance>();
FieldInfo[] fi = val1.GetType().GetFields();
foreach (FieldInfo f in fi)
{
Variance v = new Variance();
v.Prop = f.Name;
v.valA = f.GetValue(val1);
v.valB = f.GetValue(val2);
if (!v.valA.Equals(v.valB))
variances.Add(v);
}
return variances;
}
}
class Variance
{
string _prop;
public string Prop
{
get { return _prop; }
set { _prop = value; }
}
object _valA;
public object valA
{
get { return _valA; }
set { _valA = value; }
}
object _valB;
public object valB
{
get { return _valB; }
set { _valB = value; }
}
}
So on my main form, how do I go about calling the compare method and passing the static Global class inside?
example: extentions.DetailedCompare(Global, Global_bk) ? Of course this would give me an error because I cant pass a type as a variable.
Please help me, this is driving me nuts...
How about the singleton pattern ? You can pass reference to shared interface (IDoable in exable below) and still have just one instance.
I.E.:
public interface IDoable {
int Value { get; set; }
void Foo();
}
public static class DoableWrapper {
private MyDoable : IDoable {
public int Value { get;set; }
public void Foo() {
}
}
private static IDoable s_Doable = new MyDoable();
public static IDoable Instance {
get { return s_Doable; }
}
}
Singleton is the way to go here. You can do it like this:
internal class SomeClass
{
private static SomeClass singleton;
private SomeClass(){} //yes: private constructor
public static SomeClass GetInstance()
{
return singleton ?? new SomeClass();
}
public int SomeProperty {get;set;}
public void SomeMethod()
{
//do something
}
}
The GetInstance Method will return you a SomeClass object that you can edit and pass into whatever you need.
You can access the members with classname.membername.
internal static class SomeClass
{
public static int SomeProperty {get;set;}
public static void SomeMethod()
{
//do something
}
}
static void main()
{
SomeClass.SomeProperty = 15;
SomeClass.SomeMethod();
}
The only way you are going to obtain a variable with the "class" information is using reflection. You can get a Type object for the class.
namespace Foo {
public class Bar
{
}
}
Type type = Type.GetType("Foo.Bar");
Otherwise, if you are really describing a class "instance" then use an object and simply instantiate one.
C# offers no other notation for class variables.
I need to create an inherritance of an Event as a SwimmingEvent however I'm receiving an error that the constructor doens't contain 0 arguments, the problem is I don't know which arguments are meant to be passed through. Any help would be greatly appreciated.
//Base Class
class Event
{
private string m_evName;
private string m_evDate;
private string m_evTime;
private string m_evFee;
private string m_evVenue;
private List<Athlete> m_athletes;
public String EvName { get { return m_evName; } }
public String EvDate { get { return m_evDate; } }
public String EvTime { get { return m_evTime; } }
public String EvFee { get { return m_evFee; } }
public String Venue { get { return m_evVenue; } }
//Getters/Setters - Making private variables avilable in public space through class method
public Event(String EvName, String EvDate, String EvTime, String EvFee, String EvVenue)
{
m_evName = EvName;
m_evDate = EvDate;
m_evTime = EvTime;
m_evFee = EvFee;
m_evVenue = EvVenue;
m_athletes = new List<Athlete>();
}
}
//child class
class SwimmingEvent : Event
{
private String m_distance;
private String m_inOutVar;
public SwimmingEvent(String Distance, String InOrOut)
{
m_distance = Distance;
m_inOutVar = InOrOut;
}
}
Since SwimmingEvent is an Event, you need to pass all arguments that you pass to the Event's constructor to the constructor of SwimmingEvent, and then some:
public SwimmingEvent(String EvName, String EvDate, String EvTime, String EvFee, String EvVenue, String Distance, String InOrOut)
: base (EvName, EvTime, EvFee, EvVenue, Distance) {
m_distance = Distance;
m_inOutVar = InOrOut;
}
using System;
public class MyBase
{
int num;
public MyBase(int i )
{
num = i;
Console.WriteLine("in MyBase(int i)");
}
public int GetNum()
{
return num;
}
}
public class MyDerived: MyBase
{
// This constructor will call MyBase.MyBase(int i)
***//You are missing this.***
public MyDerived(int i) : base(i)
{
}
}
You need to pass all arguments back to your parent.
class SwimmingEvent : Event
{
private String m_distance;
private String m_inOutVar;
public SwimmingEvent(String Distance, String InOrOut, string evName) : base (evName,"b","c", "d", "e")
{
m_distance = Distance;
m_inOutVar = InOrOut;
}
}
May be something like this:
public class Event
{
public Event() {} // public empty ctor
....
....
}
and derived
public class SwimmingEvent : Event
{
}
In this way you will avoid (assuming that is what you want) the compile time error, as a ctor with empty arguments list is already present in base class.
If this is not what you're searching for, please clarify.
in C#, before constructor of derived class (such as SwimmingEvent constructor) is called, constructor of base class (Event class) must be called too. Arguments of call to base class's constructor are usually specified using "base" keyword like this:
class SwimmingEvent : Event
{
....
public SwimmingEvent(String Distance, String InOrOut)
:base(/*Arguments for base class constructor*/)
{
//Constructor of derived class
}
}
if you omit ":base(...)", compiler assumes calling parameterless constructor of base class, such as if you write ":base()". But there is no parameterless constructor in base class, so you get the error.
You must either create parameterless constructor in Event class, or add "base" keyword and specify arguments for calling existing Event class's constructor in SwimmingEvent's declaration.