How to set class-property and re-use it on another class? - c#

I got a class with inputs where I set values trough Class A. How can I access those property-values in Class B?
E.g.
namespace Example{
public class Inputs {
public string Something { get; set; }
}
Class A:
Inputs test = new Inputs();
test.Something = txtSomething.Text;
Class B:
//How do I access values I declared in class A, or did I do something wrong?

public class B{
public Inputs Test { get; set; }
}
var b = new B();
b.Test = new Inputs();
b.Test.Something = txtSomething.Text;
public class B{
public B(Inputs myB)
{ this.MyB = myB; }
public Inputs MyB { get; set; }
}
Inputs test = new Inputs();
test.Something = txtSomething.Text;
var b = new B(test );

Just give B a copy of test in its constructor.
public class A
{
private Inputs _test;
public A()
{
_test = new Inputs();
new B(_test);
}
}
public class B
{
private Inputs _input;
public B(Inputs input)
{
_input= input;
}
}
any changes to A._test.Somthing will also show up in B._input.Somthing.

Related

Unit testing a collection with equivalent object

I'm in search of a simple way to test that a collection contains logically equivalent object (ignoring instance) in c#.
public class BarObject
{
public string name { get; set; }
public string info { get; set; }
}
public class Foo
{
public Foo() { }
public IEnumerable<BarObject> Bars { get; set; } =
new List<BarObject>()
{
new BarObject() { name = "johndoe", info = "wierdo" }
};
}
[TestClass]
public class FooTests
{
[TestMethod]
public void TestDefaultInList()
{
Foo foo = new Foo();
//Using NUnit
CollectionAssert.Contains(foo.Bars.ToList(),
new BarObject() { name = "johndoe", info = "wierdo" }
);
}
}
The issue that I believe that I am having is that it is checking the instance of the object instead of the values within. How do I test that there is an object with specific values in an array simply without writing my own comparers?

Accessing elements of a list in another class

Lets say I have something like the following.
namespace BurgerMachine
{
public class BaseList{
private static readonly List<Bases> bList = new List<Bases>() //might need to take off readonly
{
new Bases(){ BaseID=1, BaseName="Bun"},
new Bases(){ BaseID=2, BaseName="SeededBun"}
};
public static List<Bases> GetList()
{
return bList;
}
}
public class Bases
{
public int BaseID { get; set; }
public string BaseName { get; set; }
}
}
Now I would like to access the elements of the above list from another class, is this doable with my current setup or do I need to be returning more?
I have seen a few examples of people creating a List and then adding to from another class but not trying to access elements that already exist. If such an example does exist please point me in the right direction.
First time using Lists in this fashion so I'm not quite sure what I am doing. Any help would be great. If more information is needed please ask.
Here are few implementations best way to return list.
With static class
public class BaseListProvider
{
public static readonly Bases Bun = new Bases() { BaseID = 1, BaseName = "Bun" };
public static readonly Bases SeededBun = new Bases() { BaseID = 2, BaseName = "SeededBun" };
public static IEnumerable<Bases> GetList()
{
return new[]
{
Bun,
SeededBun
};
}
}
public class Bases
{
public int BaseID { get; set; }
public string BaseName { get; set; }
}
With interface which can be helpful if you are using dependency injection
public class BaseListProvider : IBaseListProvider
{
public static readonly Bases Bun = new Bases() { BaseID = 1, BaseName = "Bun" };
public static readonly Bases SeededBun = new Bases() { BaseID = 2, BaseName = "SeededBun" };
public IEnumerable<Bases> GetList()
{
return new[]
{
Bun,
SeededBun
};
}
}
public interface IBaseListProvider
{
IEnumerable<Bases> GetList();
}
public class Bases
{
public int BaseID { get; set; }
public string BaseName { get; set; }
}
Well you could just make the list a public member like below and access it from wherever you want
public List<Bases> bList = new List<Bases>()
{
new Bases(){ BaseID=1, BaseName="Bun"},
new Bases(){ BaseID=2, BaseName="SeededBun"}
};
You can access now saying
var blist = new BaseList().bList;
With your current setup (as already commented) why can't you just call the static method saying BaseList.GetList()

C# Set from another class and Get from another class

This's Class A
Class A
{
public string uname { get; set; }
public string fname { get; set; }
}
I set values by Class B
Class B
{
private void Main(){
A aGetSet = new A();
aGetSet.uname = "James";
aGetSet.fname = "Blunt";
}
}
But when I get values in Class C, it's always return null
Class C
{
private void Main() {
A aGetSet = new A();
string username = aGetSet.uname;
string fistname = aGetSet.fname;
}
}
Does anyone has solution for this problem?
The aGetSet declared in B is an object of A. The aGetSet declared in C is another object of A. They are completely independent of each other. Changing the values of one of the objects does not affect the values of the other.
To fix this problem, you need to make it so that you are accessing the same instance in B and C.
There are lots of ways to do this. I will show you how to use the singleton pattern.
class A
{
public string uname { get; set; }
public string fname { get; set; }
private A() {} // mark this private so that no other instances of A can be created
public static readonly A Instance = new A();
}
class B
{
public void Main(){
// here we are setting A.Instance, which is the only instance there is
A.Instance.uname = "James";
A.Instance.fname = "Blunt";
}
}
class C
{
public void Main() {
B b = new B();
b.Main();
string username = A.Instance.uname;
string fistname = A.Instance.fname;
}
}
Now you just need to call C.Main to make this work!
Your have 2 different objects in 2 classes. When you are using '= new A() ' it creates new instance.
The reason why you are getting null here:
string username = aGetSet.uname;
is default value for string type (as any reference type) is null.
To pass 'the same' object from class B into class C Main method change method in class C to public Main(ref A obj). That will not create a copy and use the same instance.
Call from class B:
A aObj = new A();
aGetSet.uname = "James";
aGetSet.fname = "Blunt";
C c = new C();
c.Main(ref aObj);

XmlElement Inheritance

I would like to know if it's possible to inherit from an XmlElement field such as
public class A{
[XmlElement(ElementName = "Something", Form = XmlSchemaForm.Unqualified)]
public string Something{ get; set; }
}
public class B: A
{
}
And while using class B objects, could I have the Something XmlElement field that I could manipulate by doing things such as a try parse to make a Int32 ?
Thank you
//EDITS
Here's something that I would do with this xml element field in an other class.
public class B: A, INotifyPropertyChanged
{
public Int32? TimerValueFromApi
{
get
{
int timerValueFromApi;
return int.TryParse(base.Something, out timerValueFromApi) ? (int?) timerValueFromApi : null;
}
set
{
base.Something = value.HasValue ? value.Value.ToString(CultureInfo.InvariantCulture) : "0";
NotifyPropertyChanged("TimerValueFromApi");
}
}
}
Yes, it works:
var xml = "<B><Something>5</Something></B>";
var b = (B) new XmlSerializer(typeof(B)).Deserialize(new StringReader(xml));
Console.WriteLine(b.TimerValueFromApi); // outputs "5"
You can use some AfterDeserialization action like this:
public interface IDeserializable
{
void OnDeserialize();
}
public class A
{
[XmlElement(ElementName = "Something", Form = XmlSchemaForm.Unqualified)]
public string Something { get; set; }
}
public class B : A, IDeserializable
{
[System.Xml.Serialization.XmlIgnore]
public Int32 SomethingInt32
{
get;
set;
}
public void OnDeserialize()
{
SomethingInt32 = Int32.Parse(Something);
}
}
public class C
{
public void Deserialize()
{
System.Xml.Serialization.XmlSerializer ser = new System.Xml.Serialization.XmlSerializer(typeof(B));
var b = ser.Deserialize(streamOrStringData) as B;
b.OnDeserialize();
}
}

Protobuf Inheritance and Generics

I am attempting to use ProtoBuf net to serialize an object tree with the classes in the following format:
[ProtoContract]
class MySpecialCollectionList<T> : List<MySpecialCollection<T>>
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
class MySpecialCollection<T> : List<Special<T>>
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
class Special<T>
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public string Description { get; set; }
[ProtoMember(3)]
private readonly T _source;
T Source { get { return _source; } }
private Special()
{
}
public Special(T source)
{
_source = source;
}
}
interface IBeast
{
string Name { get; set; }
}
[ProtoContract]
class Ant : IBeast
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
class Cat : IBeast
{
[ProtoMember(1)]
public string Name { get; set; }
}
[ProtoContract]
class Dog : IBeast
{
[ProtoMember(1)]
public string Name { get; set; }
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
MySpecialCollectionList<IBeast> collectionList = GetSpecialCollectionList();
using (var fs = File.Create(#"c:\temp\protobuftest.bin"))
{
Serializer.Serialize(fs, collectionList);
fs.Close();
}
}
private MySpecialCollectionList<IBeast> GetSpecialCollectionList()
{
var ant = new Ant() { Name = "Mr Ant" };
var cat = new Cat() { Name = "Mr Cat" };
var dog = new Dog() { Name = "Mr Dog" };
var Special = new Special<IBeast>(ant);
var specialCollection1 = new MySpecialCollection<IBeast>() {
{new Special<IBeast>(ant)},
{new Special<IBeast>(cat)},
{new Special<IBeast>(dog)}
};
specialCollection1.Name = "Special Collection1";
var specialCollection2 = new MySpecialCollection<IBeast>() {
{new Special<IBeast>(ant)},
{new Special<IBeast>(dog)}
};
specialCollection2.Name = "Special Collection2";
var specialCollectionList = new MySpecialCollectionList<IBeast>() {
specialCollection1, specialCollection2 };
specialCollectionList.Name = "Special Collection List";
return specialCollectionList;
}
}
Notice how the class I am serializing (MySpecialCollectionList<T>) is derived from a List<SomeOtherClass<T>>, not just List<T>.
I am struggling to work out where to put "ProtoInclude" attributes to get this to serialize all the items in the MySpecialCollectionList. Any help would be much appreciated.
Inheritance is not an issue here since even if A : B it is not true that Foo<A> : Foo<B>. Note that protobuf-net won't use a non-default constructor, although it is possible to skip the constructor, binding to the field directly (even readonly). While you may have 6 T, I can't see (from the code) that it would ever be in doubt which closed type you intend, and if the closed type is known you should be set.
If you have a Foo<SomeBaseClass> and a number of concrete types inherited from SomeBaseClass then the markers would o on SomeBaseClass.
However, if you have a concrete scenario I can use to reproduce your issue, I'll happily take a look.
Updated re edit:
There are a couple of key points drawn out in the example:
in common with most binding APIs, XmlSerializer and IIRC DataContractSerializer, an item is either a list xor an item with values; if a collection (something implementing IList) has properties itself, they will not be serialized; encapsulation is preferred over inheritance here, i.e. something that has a Name and has a list (rather than has a Name and is a list)
protobuf-net v1 does not support interface-based serialization; v2 does, but as with XmlSerializer and DataContractSerializer you need to explicitly tell it what things it needs to expect; quite nicely, though, we can move the [ProtoMember] onto the interface itself
Here's a fully working version in v2:
using System.Collections.Generic;
using ProtoBuf;
[ProtoContract]
class MySpecialCollectionList<T>
{
[ProtoMember(1)]
public string Name { get; set; }
private readonly List<MySpecialCollection<T>> items = new List<MySpecialCollection<T>>();
[ProtoMember(2)]
public List<MySpecialCollection<T>> Items { get { return items; } }
}
[ProtoContract]
class MySpecialCollection<T>
{
[ProtoMember(1)]
public string Name { get; set; }
private readonly List<Special<T>> items = new List<Special<T>>();
[ProtoMember(2)]
public List<Special<T>> Items { get { return items; } }
}
[ProtoContract]
class Special<T>
{
[ProtoMember(1)]
public string Name { get; set; }
[ProtoMember(2)]
public string Description { get; set; }
[ProtoMember(3)]
private readonly T _source;
T Source { get { return _source; } }
private Special()
{
}
public Special(T source)
{
_source = source;
}
}
[ProtoContract]
[ProtoInclude(2, typeof(Ant))]
[ProtoInclude(3, typeof(Cat))]
[ProtoInclude(4, typeof(Dog))]
interface IBeast
{
[ProtoMember(1)]
string Name { get; set; }
}
[ProtoContract]
class Ant : IBeast
{
public string Name { get; set; }
}
[ProtoContract]
class Cat : IBeast
{
public string Name { get; set; }
}
[ProtoContract]
class Dog : IBeast
{
public string Name { get; set; }
}
public static class Form1
{
private static void Main()
{
MySpecialCollectionList<IBeast> collectionList = GetSpecialCollectionList();
var copy = Serializer.DeepClone(collectionList);
}
private static MySpecialCollectionList<IBeast> GetSpecialCollectionList()
{
var ant = new Ant() { Name = "Mr Ant" };
var cat = new Cat() { Name = "Mr Cat" };
var dog = new Dog() { Name = "Mr Dog" };
var Special = new Special<IBeast>(ant);
var specialCollection1 = new MySpecialCollection<IBeast>() {Items =
{new Special<IBeast>(ant),
new Special<IBeast>(cat),
new Special<IBeast>(dog)}
};
specialCollection1.Name = "Special Collection1";
var specialCollection2 = new MySpecialCollection<IBeast>()
{
Items =
{new Special<IBeast>(ant),
new Special<IBeast>(dog)}
};
specialCollection2.Name = "Special Collection2";
var specialCollectionList = new MySpecialCollectionList<IBeast>()
{
Items ={
specialCollection1, specialCollection2 }
};
specialCollectionList.Name = "Special Collection List";
return specialCollectionList;
}
}

Categories