I have a class A that contains a List field.
public class A
{
public List<int> list = new List<int>();
}
I would like to remove an element from the list from class B without making the list in class A static. How can I do that?
You could create an instance of class A inside a method in class B. Then you could access the list field, like this:
public class B
{
void method()
{
A a = new A();
int item = 2;
a.list.Remove(item);
}
}
A more OOP solution for this problem would be:
public class A
{
private List<int> list = new List<int>();
List<int> getList();
void setList(List<int> list);
}
Then in the code where it is used,
A a = new A();
List<int> list = a.getList();
modify list as you want
a.setList(list);
If you don't mind instantiating it, it's simply
A a = new A();
a.list...
If you don't want to instantiate a new one, you can pass an existing instance to B on its constructor:
public class B{
private A myA;
public B( A a) {
this.myA = a;
}
public doSomething(){
this.myA....
}
}
Now you can use A as a field of B.
Related
I have two similar classes A and B, which contain the following code:
//A or B depending on class
public class LogicA
{
public List<Members> MembersA { get; set; } = new List<Member>();
public void AddMember(Member member)
{
MembersA.Add(member);
}
public List<Member> GetResultA()
{
return MembersA;
}
}
I want to use the MembersA and MembersB lists in another class (say logicC).
I have seen similar questions and they mostly involve single inheritance. The process I thought to use was to create instance of lists from two different classes in the third class through multiple inheritance but in C#, only interface support multiple inheritance and I am using classes, hence my issue.
Is there any reason that you need to use inheritance only?
Generally, the way of using a member of Class is follow
class logicC
{
static void Main(string[] args)
{
LogicA logicA = new LogicA();
LogicB logicB = new LogicB();
List<Member> memberA = logicA.memberA;
List<Member> memberB = logicB.memberB;
}
}
Both Logica.GetResultA and presumably LogicB.GetResultB return List<Member>. So there is no problem
LogicC can be
class LogicC{
void NoodleOnList(List<Member> input){
....
}
}
then
LogicC lc;
lc.NoodelOnList(la.GetMembersA());
lc.NoodelOnList(lb.GetMembersb());
Well, you should re-consider your design choices and think about how to make your code less prone to change.
You can create a new class to aggregate Lists from A, B. And via Composition this new class might access Lists from other inner objects.
public class logicC {
public LogicA logicA;
public LogicB logicB;
public List<Member> GetResultC() => logicA.GetResultA().Concat(logicB.GetResultB());
}
you can use static modifier for your methods for example:
public static class LogicA
{
public static List<Members> MembersA { get; set; } = new List<Member>();
public static void AddMember(Member member)
{
MembersA.Add(member);
}
public static List<Member> GetResultA()
{
return MembersA;
}
}
and use this like that:
using YourProject;
public class LogicC
{
Members members = new();
List<Members> membersList = new();
LogicA.AddMember(member);
membersList = LogicA.GetResult();
}
My example code would looks something like this. I have two classes A and B and they both inherit abstract class.
At one point I want to make a list that is List so that I can add both classes A and into it. Lets say that later at some point I want to make a new list that is List and I want to add only A class to it. How do I do that? Since I can't access member of my A class?
abstract class Abstract
{
public string X;
public Abstract(string x)
{
X=x;
}
}
class A : Abstract
{
public int Number;
public A(string x, int number):base(x)
{
Number = number;
}
}
class B : Abstract
{
public int Age;
public A(string x, int age):base(x)
{
Age = age;
}
}
public partial class MainWindow : Window
{
List<Abstract> abstractList = new List<Abstract>();
abstractList.Add(new A("Something", 1111);
abstractList.Add(new B("Something2", 2222);
//Now at some point I want just to add A class to new list
List<A> AList = new List<A>();
for (int i=0;i<abstractList.Count;i++)
{
if(abstractList[i] is A)
AList.Add(new A(abstractList[i].x, abstractList[i].?)); //How do I do this part?
}
}
I've marked in comments part that confuses me the most. Even if you don't want to just give me the answer could you point me in direction where I should look?
I feel like I'm missing a big part of how it works here.
You can use OfType<T> on the list to only get back the objects of the type A.
AList = abstractList.OfType<A>().ToList();
Assume I have a class A that has a private List Plist and the functions necessary for basic interaction with it (adding, deleting etc). In my class B, I use these functions, but also want to iterate/search/whatever over it via LINQ in many different ways. Creating a new function for every query seems unreasonable, so I wonder if I could create a function that takes a query as an argument and applies it to the private list. I am aware that it pretty much defeats the point of having the list private in the first place, however Im wondering if it's possible
Technically, I would like it to work like this (which it obviously doesnt, but you get the idea):
public class A
{
private List<C> Plist { get; set; } = new List<C>();
public C Search(string query)
{
this.Plist.query
}
}
public class B
{
A a = new A();
a.Search("Where(i => i.AnotherListInC.Contains(SomeObject))");
}
Is there a way to access a private property with complex LINQ queries, or more generally, concatenate a string to existing code to create new code?
If you need to use String as parameter it will be hard as you would have to emit code.
If you just want to search private list than create method that accepts predicate as parameter:
public class A
{
private List<C> Plist { get; set; } = new List<C>();
public IEnumerable<C> Search(Func<C, bool> predicate)
{
return this.Plist.Where(predicate);
}
}
public class B
{
public void SomeMethod()
{
A a = new A();
a.Search(i => i.AnotherListInC.Contains(SomeObject));
}
}
Similar method can be written for any Linq method. Just create method that accepts the same parameters as Linq method except of first parameter (IEnumerable<TSource>).
In case you want all Linq methods available you can implement IEnumerable<C> on your class A
public class A : IEnumerable<C>
{
private List<C> Plist { get; set; } = new List<C>();
public IEnumerator<C> GetEnumerator()
{
return ((IEnumerable<C>)Plist).GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return ((IEnumerable<C>)Plist).GetEnumerator();
}
}
public class B
{
public void SomeMethod()
{
A a = new A();
a.Where(i => i.AnotherListInC.Contains(SomeObject));
a.Any(i => i.AnotherListInC.Contains(SomeObject));
}
}
I have a few classes. Lets say:
public class A
{
public void SomeAction()
{
Debug.Write("I was declared in class: and my name is:");
}
}
And
public class B
{
public static A myClass = new A();
}
public class C
{
public static A myClass = new A();
}
public class D
{
public static A myClass = new A();
}
What I want "SomeAction" in class A to do is to print out which class it was initialized in.
So that for example in another class I called C.myClass.SomeAction(); it would print out "I was declared in class C my name is myClass"
I hope this makes sense.
The reasons im doing this is for debugging within automated testing. I understand its not the best way to do things but its a requirement of the business.
This requirement can be satisfied without inheritance or passing the object; we can get the name of the class that calls the constructor from within the body of the constructor by examining the stack.
public class A
{
private string _createdBy;
public void SomeAction()
{
Console.WriteLine("I was declared in class [{0}]", _createdBy);
}
public A()
{
var stackFrame = new StackFrame(1);
var method = stackFrame.GetMethod();
_createdBy = method.DeclaringType.Name;
}
}
In terms of performance, I am assuming that you are not creating many instances of these objects. You could also predicate this on whether you are doing a DEBUG build or on some other setting, so that this stuff is skipped entirely in your production executables.
Since you only reference an instance of class A in your other classes, I think there is no other way then setting a reference to the type which created class A, like eddie_cat already mentioned. You could do something like this:
public class B
{
public static A myClass = new A(typeof(B));
}
And then your class A would look like:
public class A
{
// store the parent type
private Type mParentClass;
// provide parent type during construction of A
public A(Type parentClass)
{
mParentClass = parentClass;
}
// note that method cannot be static anymore, since every instance of A might
// have a different parent
public void SomeAction()
{
// access field where parent type is stored.
Debug.Write("I was declared in class: {0} and my name is:",mParentClass.Name);
}
}
I think you have two choices. Either set a property in A, or inherit from A. Personally, I prefer inheriting from A, because then A could just use GetType().
public class A
{
public void SomeMethod()
{
Debug.Write(string.Format("I was declared in class: {0}",this.GetType()));
}
}
public class B : A
{
}
var instanceOfB = new B();
instanceOfB.SomeMethod();
How can I access an element by index of a member List via a property? For example:
public class foo{
private List<type> list = new List<type>;
public List{
get{/*basically, what goes here?*/}
}
}
//Much later....
foo Foo = new foo();
Console.WriteLine(Foo.List[1]);
One thing to consider is what ability you want to provide to update the list. If you just expose the list as a get-only property, then there's nothing stopping someone from modifying the list:
public class foo{
private List<type> list = new List<type>;
public List<type> List{
get{return list}
}
}
//Much later....
foo Foo = new foo();
Foo.List.Clear(); // perfectly legal
If, however, you want a "read-only" list exposed, then you can expose the list as read-only:
public class foo{
private List<type> list = new List<type>;
public IList<type> List{
get{return list.AsReadOnly()}
}
}
//Much later....
foo Foo = new foo();
Foo.List.Clear(); // not possible
EDIT
Based on your comment to another question, it is unclear whether you want to expose the list as a property or access items by index. For the latter you can add an indexer to the class:
public class foo{
private List<type> list = new List<type>;
public type this[int i]{
get{return list[i]}
get{list[i] = value}
}
}
//Much later....
foo Foo = new foo();
Console.WriteLine(Foo[1]);
Since you already have a list, you can just return that list in the property
public class foo{
private List<type> list = new List<type>;
public List<type> List{
get{ return list; }
}
}