I was not able to find an answer to this because I didn't know how to put it.
I have a class Car() and a class Owner(). What I need is to have an object of 'owner', as a simple attribute of my Car() class, so I can pass it as a argument once I instanciate my Car() object.
My Owner() Class:
class Owner
{
public Owner(string address){
this.address = address;
}
}
My Car() Class:
class Car
{
public Car(object owner){ // what type to use?
this.owner = owner;
}
private object owner; // what type to use?
}
And my Main() Class:
static void Main(string[] args){
Owner owner1 = new Owner("street foo city bar");
Car car1 = new Car(owner1); // this needs to work
}
Obviously, using the 'object' type for the attribute didn't do it. Once I print I get 'myProjectName.Owner'. Thank you in advance.
You can write your code as below, writing public methods to return the objects you want.
class Program
{
static void Main(string[] args)
{
Owner owner1 = new Owner("street foo city bar");
Car car1 = new Car(owner1); // this needs to work
Console.WriteLine("Car 1 owner address : " + car1.getOwner().getAddress());
Console.ReadKey();
}
}
class Car
{
private Owner owner; // same here\
public Car(Owner owner)
{ // use Owner class
this.owner = owner;
}
public Owner getOwner() // write a public method to return owner
{
return this.owner;
}
}
class Owner
{
private string address; // this
public Owner(string address)
{
this.address = address;
}
public string getAddress() // write a public method to return address
{
return this.address;
}
}
public class Car
{
public Car(Owner owner)
{
this.Owner = owner;
}
//Since Owner is public, you don't have to create a getter method for this. i.e GetOwner()
public Owner Owner;
}
public class Owner
{
//Since address is private, you'll have to create a public getter for this
private string address;
public Owner(string address)
{
this.address = address;
}
//public getter for the address
public string GetAddress()
{
return this.address;
}
}
public class Main
{
static void main(string[] args)
{
Owner owner1 = new Owner("street address");
Car car1 = new Car(owner1);
car1.Owner.GetAddress();
}
}
Related
I have a ParentClass. Two classes are inherit from it, FirstChildClass and SecondChildClass. A class MultipleValueTypes contains a Dictionary and a method that adds values to it. My intention is to be able to pass values of different classes, which inherit from the same abstract class to the value parameter of the Dictionary. Therefore, I initialize the dictionary with the value List<ParentClass> so that I would be able to add objects made with the child classes to the Dictionary. I can do this, but I cannot access them, therefore in the abstract class I create a way to tell them apart, a virtual method that both the children classes override to return their own class type.
I test the values they return against the enum itself and based on whether the condition is fulfilled, the object would be casted as what it is instead of a List<ParentClass>. Is this the wrong approach? Is this impossible?
I think it should work, because in my thinking the FirstObject and SecondObject are still objects of their respective classes, so casting should work and I should be able to access the overridden method.
What doesn't work: I cannot access the method that returns what type of class it is, because it only gets methods from the List<ParentClass>.
What I've tried so far: searching for a way to access the method, but I did not find any.
What I still need help with: everything mentioned above.
public abstract class ParentClass
{
public string Name { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
}
public class FirstChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public FirstChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the FirstChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
private string _randomvalue;
public string RandomValue { get => _randomvalue; set => _randomvalue = value; }
public SecondChildClass(string Name) : base(Name)
{
}
public void ReturnMessage()
{
Console.WriteLine("This is the SecondChildClass");
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public Dictionary<string, List<ParentClass>> ADictionary = new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if (!ADictionary.ContainsKey(Name))
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
class Program
{
static void Main(string[] args)
{
FirstChildClass FirstObject = new FirstChildClass("FirstObject");
SecondChildClass SecondObject = new SecondChildClass("SecondObject");
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if(TestDictionary.ADictionary["FirstObject"].TypeOfClass() == ParentClass.ChildClasses.FirstChildClass) ///List<ParentClass>' does not contain a definition for 'TypeOfClass' and no accessible extension method 'TypeOfClass' accepting a first argument of type 'List<ParentClass>' could be found (are you missing a using directive or an assembly reference?)
{
TestDictionary.ADictionary["FirstObject"] = (FirstChildClass)TestDictionary.ADictionary["FirstObject"]; ///Cannot convert type 'System.Collections.Generic.List<Dictionary.ParentClass>' to 'Dictionary.FirstChildClass
}
}
}
You forgot to use indexer of the list value of the key of the dictionary here:
==> TestDictionary.ADictionary["FirstObject"][0]
Here is your code now refactored too:
class Program
{
static void Main(string[] args)
{
var FirstObject = new FirstChildClass("FirstObject");
var SecondObject = new SecondChildClass("SecondObject");
FirstObject.ReturnMessage();
SecondObject.ReturnMessage();
MultipleValueTypes TestDictionary = new MultipleValueTypes();
TestDictionary.AddObject("FirstObject", FirstObject);
TestDictionary.AddObject("SecondObject", SecondObject);
if ( TestDictionary.ADictionary["FirstObject"][0].TypeOfClass()
== ParentClass.ChildClasses.FirstChildClass )
{
TestDictionary.ADictionary["FirstObject"][0]
= (FirstChildClass)TestDictionary.ADictionary["FirstObject"][0];
}
Console.ReadKey();
}
}
public abstract class ParentClass
{
public string Name { get; set; }
public string RandomValue { get; set; }
public ParentClass(string Name)
{
this.Name = Name;
}
public virtual void ReturnMessage()
{
Console.WriteLine($"This is the {this.GetType().Name} instance");
}
public virtual ChildClasses TypeOfClass()
{
return ChildClasses.NoChildClass;
}
public enum ChildClasses
{
NoChildClass = 0,
FirstChildClass = 1,
SecondChildClass = 2
}
}
public class FirstChildClass : ParentClass
{
public FirstChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.FirstChildClass;
}
}
public class SecondChildClass : ParentClass
{
public SecondChildClass(string Name)
: base(Name)
{
}
public override ChildClasses TypeOfClass()
{
return ChildClasses.SecondChildClass;
}
}
class MultipleValueTypes
{
public readonly Dictionary<string, List<ParentClass>> ADictionary
= new Dictionary<string, List<ParentClass>>();
public void AddObject(string Name, ParentClass variable)
{
if ( !ADictionary.ContainsKey(Name) )
{
ADictionary.Add(Name, new List<ParentClass>());
}
ADictionary[Name].Add(variable);
}
}
If the intention is to cast the whole list from List<ParentClass> to List<FirstChildClass> and List<SecondChildClass>, then Linq is your friend, just use the Cast function:
List<FirstChildClass> firstChildClasses = TestDictionary.ADictionary["FirstObject"]
.Cast<FirstChildClass>().ToList();
List<SecondChildClass> secondChildClasses = TestDictionary.ADictionary["SecondObject"]
.Cast<SecondChildClass>().ToList();
Main class:
public class Main
{
private string param;
public Main(string param) { this.param = param; }
public List<Foo> Foos
{
get {return GetFoos();}
// add functionality of saving Foo (single item, not the whole list) here?
}
private List<Foo> GetFoos()
{
List<Foo> x = new List<Foo>();
return x;
}
public class Foo
{
public int Id { get; set; }
public string Name { get; set; }
// or maybe here?
}
}
Test class:
public class Test
{
public Test()
{
var main = new Main("hi!");
// usage 1
main.Foos.Find(p => p.Id == 1).Save(); // method visible here
var foo = new Main.Foo();
// usage 2
foo.Save(); // method not visible here
}
}
Comments in the code basically say everything:
1. I want to implement the Save() method of the object Foo.
2. Method can be called only if the Foo object is picked up from the list (usage 1).
3. Method can not be called from the Foo object created alone (usage 2).
4. Method must use private value of the property param passed during initialization of the main class.
You can use an interface to hide the method Save.
To do this, the Save method must be implemented explicitly.
Additionally you need a link to the main object. In your subclass Foo you can access the private attribute from Main directly.
Interface:
public interface IFoo
{
int Id { get; set; }
string Name { get; set; }
void Save();
}
Class:
public class Main
{
private string param;
private List<IFoo> foos = new List<IFoo>();
public Main(string param) { this.param = param; }
public List<IFoo> Foos
{
get { return this.foos; }
}
public void AddFoo(int pnId, string pnName)
{
this.foos.Add(new Foo(this) { Id = pnId, Name = pnName });
}
public class Foo : IFoo
{
private Main moParent;
public Foo() { }
public Foo(Main poParent)
{
this.moParent = poParent;
}
public int Id { get; set; }
public string Name { get; set; }
//Implement interface explicitly
void IFoo.Save()
{
if (this.moParent == null)
throw new InvalidOperationException("Parent not set");
Console.WriteLine($"Save with Param: {this.moParent.param}, Id: {this.Id} Name: {this.Name}");
//Save Item
}
}
}
Usage:
var main = new Main("hi!");
main.AddFoo(1, "Foo1");
// usage 1
main.Foos.Find(p => p.Id == 1).Save(); // method visible here
var foo = new Main.Foo();
// usage 2
//foo.Save(); // Save is not visible here
I am trying to add entries in dictionary array list but i don't know which arguments to set in the People Class in the main function.
public class People : DictionaryBase
{
public void Add(Person newPerson)
{
Dictionary.Add(newPerson.Name, newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
using this seem to give me error
static void Main(string[] args)
{
People peop = new People();
peop.Add("Josh", new Person("Josh"));
}
Error 2 No overload for method 'Add' takes 2 arguments
This peop.Add("Josh", new Person("Josh"));
should be this
var josh = new Person() // parameterless constructor.
{
Name = "Josh" //Setter for name.
};
peop.Add(josh);//adds person to dictionary.
The class People has the method Add which only takes one argument: a Person object. The Add on the people class method will take care of adding the it to the dictionary for you and supplying both the name (string) argument and the Person argument.
Your Person class only has a parameterless constructor, which means that you need to set your Name in the setter. You can do this when you instantiate the object like above.
For your design this would solve the problem:
public class People : DictionaryBase
{
public void Add(string key, Person newPerson)
{
Dictionary.Add(key , newPerson);
}
public void Remove(string name)
{
Dictionary.Remove(name);
}
public Person this[string name]
{
get
{
return (Person)Dictionary[name];
}
set
{
Dictionary[name] = value;
}
}
}
public class Person
{
private string name;
private int age;
public string Name
{
get
{
return name;
}
set
{
name = value;
}
}
public int Age
{
get
{
return age;
}
set
{
age = value;
}
}
}
And in Main:
People peop = new People();
peop.Add("Josh", new Person() { Name = "Josh" });
How would it be possible to reference an external string in an external class.
e.g.
Class1.cs:
MessageBox.Show(mystring);
Class2.cs:
public static void myMethod()
{
string mystring = "foobar";
// some logic here
}
If I right understood your question, you can do something like this:
public class2
{
public static string MyString
{
get {return "foobar"; }
}
}
public class1
{
public void DoSomething()
{
MessageBox.Show(class2.MyString );
}
}
Something like this?
public static class Foo
{
public const string FOO_CONST = "value";
}
public class Bar
{
public void Bar()
{
Console.WriteLine(Foo.FOO_CONST);
}
}
If you create a new instance of Class2 you can make MyString public or pull it out into a get method:
//In Class1
Class2 class2 = new Class2();
MessageBox.Show(class2.Mystring());
//In Class2
public string Mystring{ get; set; }
Or you could return the string from the method
public static string myMethod()
{
string myString = "foobar";
//logic goes here
return myString;
}
//In Class1
Class2 class2 = new Class2();
MessageBox.Show(class2.MyMethod());
Based on your clarification to your question:
I am trying to check a boolean value in a method in class2. E.g. if
the method run in class2 changes the boolean value in that method, the
method in class1 can check this and do some logic
You could do something like this:
class Class1 {
Class2 myClass = new Class2();
public void ActivityMethod() {
myClass.MethodThatMayChangeBoolean();
if(myClass.myBoolean) {
// Response to a truth change.
} else {
// Respond to a false change.
}
}
}
class Class2 {
public boolean myBoolean { get; }
public void MethodThatMayChangeBoolean() {
// Do stuff in here that may change boolean.
}
}
You will need to use Properties
private static string _mystring = "foobar";
public static string mystring
{
get { return _mystring ; }
set { _mystring = value; }
}
Or use auto properties and initialize their values in the static constructor of the class:
public static string mystring { get; set; }
public static MyStaticClass()
{
mystring = "foobar";
}
I have the class PGMain as the SelectedObject in the propertygrid:
[DefaultPropertyAttribute("Basic")]
[Serializable]
public class PGMain
{
private TestClass m_TEST = new TestClass();
[CategoryAttribute("TEST")]
public TestClass TEST
{
get { return m_TEST; }
set { m_TEST = value; }
}
// More members are here
}
Now I would like to expand the members of the TestClass in the PropertyGrid. So I tried the following:
[Serializable]
[DescriptionAttribute("Expand to see the options for the application.")]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class TestClass : ExpandableObjectConverter
{
[CategoryAttribute("test-cat"), DescriptionAttribute("desc")]
public string Name = "";
[CategoryAttribute("test-cat"), DescriptionAttribute("desc")]
public object Value = null;
[CategoryAttribute("test-cat"), DescriptionAttribute("desc")]
public bool Include = true;
public override bool CanConvertTo(ITypeDescriptorContext context, System.Type destinationType)
{
if (destinationType == typeof(TestClass))
return true;
return base.CanConvertTo(context, destinationType);
}
}
The result is that there is an expandable-icon in front of the TestClass in the propertygrid but it can not be expanded. What am I missing?
Just to be clear: I can show expandable members of the PGMain class but NOT expandable members of the members of the PGMain class like the Test-member in PGMain.
Edit:
No I have 2 classes NOT 1.
[DefaultPropertyAttribute("Basic")]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class fooA
{
private fooB m_TestMember = new fooB();
[Browsable(true)]
[CategoryAttribute("Test category"), DescriptionAttribute("desctiption here")] // <<<<< this one works.
[TypeConverter(typeof(fooB))]
public fooB TestMember
{
get { return m_TestMember; }
set { m_TestMember = value; }
}
}
[DefaultPropertyAttribute("Basic")]
[TypeConverter(typeof(ExpandableObjectConverter))]
public class fooB
{
private string m_ShowThisMemberInGrid = "it works"; // <<<<< this doesn NOT work
[CategoryAttribute("Tile"), DescriptionAttribute("desctiption here")]
public string ShowThisMemberInGrid
{
get { return m_ShowThisMemberInGrid; }
set { m_ShowThisMemberInGrid = value; }
}
public override string ToString()
{
return "foo B";
}
}
But I did solve the problem (by coincidence). It appears that public variables are not listed in the propertygrid. It HAVE to be properties with getters and setters. That was the solution. So the above snippet solved the problem. Thanks for your replies anyway :).
Wrong:
[CategoryAttribute("Tile"), DescriptionAttribute("desctiption here")]
public string Name = "";
Good:
private string m_Name = new string();
[CategoryAttribute("Tile"), DescriptionAttribute("desctiption here")]
public string Name
{
get { return m_Name; }
set { m_Name = value; }
}
Sorry I misinterpret the question.
You can find more details on these links
http://msdn.microsoft.com/en-us/library/aa302326.aspx#usingpropgrid_topic6a
http://www.codeproject.com/KB/miscctrl/bending_property.aspx
http://msdn.microsoft.com/en-us/library/aa302334.aspx
Hope it helps :)
UPDATE:
I copied the code from here
And modified like this.
public class SamplePerson
{
public string Name
{
get;
set;
}
public Person Person
{
get;
set;
}
}
And in the form I have done something like
SamplePerson h = new SamplePerson();
h.Person = new Person
{
Age = 20,
FirstName = "f",
LastName = "l"
};
this.propertyGrid1.SelectedObject = h;
And its working for me.
Provide Browsable as false for properties you don't want to display in the property grid.
[Browsable(false)]
public bool Include
{
get;set;
}