I have a total of 5 classes to which I always create an object. From this collection of objects a list is created with different types of objects in the list.
List<object> objectsEntries = new List<object>();
All these objecte have properties that I would like to use.
However, this turns out to be a bit confusing. Because for each entry in the list I first have to check which type it is. Then I have to cast the object to be able to use it.
Like this:
public void DoSomething(object objectsEntry)
{
if (objectsEntry is Class1)
{
Class1 commandTyped = (Class1)objectsEntry;
// Now I can use the properties of Class1
// e.g.
// Console.WriteLine(commandTyped.Name);
}
else if (objectsEntry is Class2)
{
Class2 commandTyped = (Class2)objectsEntry;
// Now I can use the properties of Class2
// e.g.
// Console.WriteLine(commandTyped.Name);
}
}
But the whole method becomes very confusing and no matter where I want to use the objecte it comes to problems, because I always have to determine the type before and then cast it.
Are there any possible solutions or approaches to this?
CodePudding user response:
I would like to do this in this way:
public interface ISomeClasses
{
int Id { get; set; }
}
public class SomeClass1 : ISomeClasses
{
public int Id { get; set; }
}
public class SomeClass2 : ISomeClasses
{
public int Id { get; set; }
}
public class Main
{
public void DoSomething(object objectsEntry)
{
if (objectsEntry is ISomeClasses someClass)
{
Console.WriteLine(someClass.Id);
}
}
}
Short explain:
- you create an interface with property which you're interesting in
- create few classes which all implements the same interface
- and in yours method called "DoSomething" you could check if object what you have implement the interface and if yes you assign it to variable called "someClass" and you have there access to property which you're interesting in
CodePudding user response:
If you create an interface containing the method DoSomething()
, you can inherit from that interface in all your custom classes and implement the desired method body of DoSomething()
for each, e.g.:
public interface IBase
{
// not needed, but should be included if all
// the classes that will ever inherit from IBase
// are expected to have the Name member
string Name { get; }
void DoSomething();
}
public class Class1 : IBase
{
public string Name { get; set; }
public int Age { get; set; }
public void DoSomething()
{
Console.WriteLine($"{Name} ({Age} years)");
}
}
public class Class2 : IBase
{
public string Name { get; set; }
public void DoSomething()
{
Console.WriteLine(Name);
}
}
// Other Class* implementations
You can then create a list of your interface type and populate it with objects of your custom classes. Calling DoSomething()
on each entry will then call the specified implementation for the appropriate Class*
type.
List<IBase> entries = new()
{
new Class1 { Name = "Sarah", Age = 43 },
new Class2 { Name = "Peter" }
};
foreach (var entry in entries)
{
entry.DoSomething();
}
produces:
Sarah (43 years)
Peter
Example fiddle here.
Alternatively, if all your custom classes share some properties and the DoSomething()
method body is identical for all (or most of) your custom classes, you could define the shared properties and the implementation of DoSomething()
in a base class that all your custom classes then inherit from.
(By making DoSomething()
virtual
, you can override
the implementation of DoSomething()
for the custom class(es) that need a customized implementation.)
public class BaseClass
{
public string Name { get; set; }
public virtual void DoSomething()
{
Console.WriteLine(Name);
}
}
public class Class1 : BaseClass
{
public int Age { get; set; }
public override void DoSomething()
{
Console.WriteLine($"{Name} ({Age} years)");
}
}
public class Class2 : BaseClass { }
public class Class3 : BaseClass { }
public class Class4 : BaseClass { }
public class Class5 : BaseClass { }
List<BaseClass> entries = new()
{
new Class2 { Name = "Anne" },
new Class3 { Name = "Peter" },
new Class5 { Name = "Jonathan" },
new Class1 { Name = "Sarah", Age = 43 },
new Class4 { Name = "Jill" }
};
foreach (var entry in entries)
{
entry.DoSomething();
}
produces:
Anne
Peter
Jonathan
Sarah (43 years)
Jill
Example fiddle here.