Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
public class Kuku
{
private LinkedList<MyClass> m_list;
public IEnumerable<MyClass> Locations { get { return m_list; } }
}
I need to implement in public class FindAllMyClass
the method which iterates all MyClass objects in Kuku - I don't know how do I use Locations property from Kuku.
Should I define IEnumerable Locations or just make LinkedList m_list to be public property?
Should I define IEnumerable<MyClass> Locations or just make LinkedList<MyClass> m_list to be a public property?
public class FindAllMyClass
{
public void itMethod(Kuku input)
{
//This is not correct
foreach (MyClass c in input.Locations)
{
}
}
}
Why to define IEnumerable Locations and not just make LinkedList m_list to be public property?
Several possible reasons:
What if later you decide you don't want to implement it as a LinkedList<> but as a regular List? Or a lazy-loaded collection type? or an array?
Exposing the collection as a generic IEnumerable<T> allows you to change out the internal implementation later without changing the public contract.
If you make the collection a property (with get; set; accessors) you are allowing clients to add to, remove from, even replace the entire list. Exposing it as IEnumerable indicates that the list is intended to be read-only (unless you expose Add methods somewhere else).
I don't know how do I use Locations property from Kuku.
Sure you do - you're already doing it in your sample:
foreach (MyClass c in input.Locations)
{
}
Or you can use Linq to search for or aggregate data from the collection (foreach is still appropriate for updating the instances.
You could use LINQ to object:
input.Locations.Where(x=> x.Property1 == value1 && x.Property2 > value2);
IEnumerable gives you a way to expose a list from your class which has the following properties:
It is implementation independent - you can change what sort of list you use internally without needing to change everything which uses your class
It integrates well with LINQ, foreach and various other language constructs
It provides a read only view on the list, so no chance of others updating the list (inserting/deleting items)
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 2 years ago.
Improve this question
I have some code which iterates through all classes implementing an interface. This works fine, example code below:
// Interface
public interface ICommand
{
string name { get; }
}
// Test class implementing interface and overrides value
public class TestCommand : ICommand
{
public string name { get { return "test"; } }
}
// Get all types implementing ICommand; This works
IEnumerable<Type> _commands = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).Where(t => t.GetInterfaces().Contains(typeof(ICommand)));
// Iterate through all classes implementing ICommand; This works as well
foreach (Type _type in _commands)
{
// _type is the type of the class, which implements ICommand
_type.GetInterface(nameof(ICommand)) // This returns the Type of the interface, if i print it in console "ICommand"
// Here I would like to access the "name" property of the type, but i don't know how
}
Now the question: As I said in the comment in the code: How can I "cast" the return value of _type.GetInterface(nameof(ICommand)) to the instance of the interface of the class, so i can access for example the name property of for example the TestCommand class?
I searched the web for hours now but sadly i could not find anything, that answers this
So, any help would be really appreciated!
If there are any important informations I missed, comment and i will edit this post
I think what you want to do is this (using IsAssignableFrom):
var commandTypes = AppDomain.CurrentDomain.GetAssemblies().SelectMany(assembly => assembly.GetTypes()).Where(t => typeof(ICommand).IsAssignableFrom(t))
To create an instance of an object you can then do something like this:
foreach (var type in commandTypes)
{
var commandObjectInstance = Activator.CreateInstance(type);
Console.WriteLine(commandObjectInstance.Name);
}
There is a lot of assumptions here about the classes always having a parameterless constructor.
Also, reflection, which is what is being used here, comes with some drawbacks, for example performance or that things happen at runtime instead of compile time, this is something you should look more, and try to understand if you want to search assemblies for types and/or dynamically creating instances of those types.
Without more background information on why you are taking this approach, i cant tell you if it is good or bad or if you should do something else, but there might be other approaches, even some that might not have much of a downside. In the right scenario what you are doing can also be perfectly valid.
If I understand what you are doing this should get you what you are looking for. This would depend on the classes that you are loading having a public parameterless constructor but basically you need an instance of the class that you are loading in order to access the name property defined on your interface.
foreach (Type _type in _commands)
{
// Here I would like to access the "name" property of the type, but i don't know how
ICommand _command = (ICommand)Activator.CreateInstance(_type);
Console.Out.WriteLine(_command.name);
}
So i got the solution with the help of #StevenWiliams and #JimWolff
For anyone who for some reason has the same problem, here is my udated code:
IEnumerable<Type> _commands = AppDomain.CurrentDomain.GetAssemblies().SelectMany(x => x.GetTypes()).Where(t => t.GetInterfaces().Contains(typeof(ICommand)));
foreach (Type _type in _commands)
{
ICommand _command = (ICommand)Activator.CreateInstance(_type);
Debug.Log("Name: " + _command.name);
}
The problem I faced was, that I forgot, that classes can have multiple instances and therefor i cant get the value of the class directly. Creating an instance fixes this problem.
Again, credits to #StevenWiliams and #JimWolff.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 3 years ago.
Improve this question
Consider a simple class
public class MyClass
{
private int myProperty
...
public int MyProperty
{
get
{
return myProperty;
}
set
{
// some evaluation/condition
myProperty= value;
}
}
...
}
Now, if I want to create an empty constructor where I set default values for the class properties I could do this either this way:
public MyClass()
{
myProperty = 1;
...
}
or this way:
public MyClass()
{
MyProperty = 1;
...
}
Both examples seem valid, since I would never set a default value, that doesn't meet the requirements in the setter evaluation.
The question is, is there a best practice or doesn't it matter anyway?
What would be the advantage of one or the other be (as I can't find any)? Is there some reference, where this question is adressed?
So far I have come across code from many different developers that use either or both ways...
You can use both. But i prefer the first one. Why? Because the value that the property uses is directly assigned. For C# 6 above, you can use default value in a property directly without using constructor.
public class Person
{
public string FirstName { get; set; } = "<first_name>";
public string LastName { get; set; } = "<last_name">;
}
I personally like to set it as you done in first block.
For me it serve as additional fact of method is constructing object, not using alredy constructed. Also it makes me sure that properties is not called (they transform to set/get functions which results in couple of excess instruction).
But i believe that both variants are valid and maybe compiler optimizes properties to direct assignment.
For simple data first method is ok. But on more complex data, you could have a condition in the set (depending to another variable for example, set { if (Config.TestEnv) ...} so if you directly set the private value, you could be in trouble.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I have a program I'm writing that has a form with around 15 inputs that describe a type of machine that we make (model, length, width, height, motor type, color, etc). There are 12 different models of this machine so I have a sub class "machine" and then 12 separate classes that inherit the "machine class". In my form, one of the inputs the user selects is the model. I'm trying to figure out a way to pass the 15 items to the specific "model" class fields without having to type it out 12 times with a case/switch (based on which model is selected). Is there a way to pass the inputs to the parent class and then when you figure out which specific class you need to create, reference the data that was stored in the parent class? I hope that makes sense what I'm saying. I'm struggling with describing the situation. If I can provide any more info please let me know!!
Thanks!
I would suggest you to write an interface, let's say something like IMachineModel with the required methods/properties. Write as many classes as models you have and implement the previously created interface.
Provide in each concrete class the logic required. Then you only need to instantiate the suitable class and use its properties and methods implemented from the interface.
Quick Example:
public class FirstConcreteMachineModel : IMachineModel
{
public string Model { get; set; }
public void DoSomething()
{
Console.WriteLine("I am a machine of type 1");
}
}
public class SecondConcreteMachineModel : IMachineModel
{
public string Model { get; set; }
public void DoSomething()
{
Console.WriteLine("I am a machine of type 2");
}
}
public class MachineModelFactory
{
public static IMachineModel CreateMachineModel(string type)
{
//switch with all possible types
switch (type)
{
case "one":
return new FirstConcreteMachineModel { Model = type };
case "two":
return new SecondConcreteMachineModel { Model = type };
default:
throw new ArgumentException("Machine type not supported");
}
}
}
Then you can use it like:
IMachineModel machine = MachineModelFactory.CreateMachineModel("two");
machine.DoSomething();
It would print
I am a machine of type 2.
To add to Areks's answer -- you could create a factory that given the inputs returns a class that implements IMachineModel .... Internally you have a number of options of how to determine the concrete class including your switch statement or chain of responsibility
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I have a class in which I operate some methods.
public class MyClass
{
public static List<ObjectA> MyField;
public static Object MyMethod()
{
List<ObjectA> anotherObjectA = new List<ObjectA>();
// I do something with anotherObjectA...
// after processing something now I want to keep the current status of anotherObjectA to MyField:
MyField = anotherObjectA;
// and now I want to work just with anotherObjectA. The problem is that whatever I work with anotherObjectA it changes also MyField
}
}
How can i achieve what I am trying to do
You can do
MyField = new List<ObjectA>(anotherObjectA);
This will create a copy of the list. However, any changes to the objects in the list will be visible in both. You'll have to decide for yourself how deep your copy has to be. If you really want a deep copy, you'll need to provide a mechanism for ObjectA to make a copy of itself, iterate over the original list, and add a copy of each object to the target list.
MyField and anotherObjectA reference same object. So if you change MyField it also changes anotherObjectA.
So First you need to create two List objects:
MyField = new List<ObjectA>(anotherObjectA);
This will create two list objects but the ObjectA objects inside the list are still referencing to the same.
MyField.First() == anotherObjectA.First() // returns true;
If you want to make a complete copy you also need to create a copy of objects inside anotherObjectA
public class ObjectA
{
public ObjectA() { } // Normal constructor
public ObjectA(ObjectA objToCopy) { /* copy fields into new object */ }
}
MyField = anotherObjectA.Select(obja => new ObjectA(obja)).ToList();
with this solution, changing objects inside MyField will not affect objects inside anotherObjectA unless ObjectA also contains reference types.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 months ago.
Improve this question
I'm not talking about generic classes that declare properties or fields with the type of a generic parameter. I'm talking about generic properties which could be applied to both generic and non-generic classes.
I'm not talking about this:
public class Base<T>
{
public T BaseProperty { get; set; }
}
I'm talking about this:
public class Base
{
public T BaseProperty<T>
{
get
{
// Insert magic
}
set
{
// Insert magic
}
}
}
Or this:
public class Base<U>
{
public T BaseProperty<T>
{
get
{
// Insert magic
}
set
{
// Insert magic
}
}
public U OtherBaseProperty { get; set; }
}
The usage would go something like this:
var b = new Base();
b.BaseProperty<int> = 42;
int i = b.BaseProperty<int>;
b.BaseProperty<string> = "Hi";
string s = b.BaseProperty<string>;
Or for the second example:
var b = new Base<string>();
b.BaseProperty<int> = 42;
int i = b.BaseProperty<int>;
b.OtherBaseProperty = "Hi";
string s = b.OtherBaseProperty;
The // Insert Magic refers to handling each call to the generic property getter or setter that has a different type for the type parameter.
For example this:
b.BaseProperty<int> = 42;
Needs to be handled differently to:
b.BaseProperty<string> = "Hi";
I would envisage that for each type T if the getter is called before the setter is called then default(T) is returned.
When the setter is called the value is stored per type T so that when the getter is subsequently called the previous value that was set for that type is returned.
Note that under the covers properties are just methods.
Do you think this would be useful?
I've had a couple of times where I would have liked the ability to do this, yes.
However, the syntax involved would be pretty ugly, and it's sufficiently rarely useful that I think I prefer to just suck it up and go with generic methods.
No .
Without a killer use case, no. You can already achieve the same thing with a pair of generic methods, should you need it.
No.
Generic methods make sense, because they embody some (generic) operation that can sensibly be applied to different types.
But properties only make sense as uniquely named values with definite content. 'Generic properties', like you suggest, really only amounts to like-named properties with different signature and different content.
Here's one example where it would have been handy for me, if it would have been possible.
var settings = new Settings();
int timeout = settings<int>["CacheInMinutes"];
Where Settings loads an XML file of configuration variables.
That, compared to:
var settings = new Settings();
int timeout = int.Parse(settings["CacheInMinutes"]);
Really not much of a difference, but hey, I still would have preferred the generic indexer.
well, I have the situation that need generic property in non-generic class.
Example you have IComponent class that want to provide its parent IContainer with property Parent, since the component can belong to any container type. so you need to provide generic property rather than generic method
Component c = new Component();
Container p = new Container();
p.Add(c);
and then you access its parent using generic property (not aplicable now)
c.Parent.ContainerProperty;
c.Parent.ContainerMethod();
rather using verbose method like
c.Parent().ContainerProperty;
c.Parent().ContainerMethod();
Well, in this case generic property is more beautiful and make sense, since you don't need to input any argument.
If for some bizarre reason you decided you wanted it, you could sort of fake it with methods:
public class Thing
{
Dictionary<Type, object> xDict = new Dictionary<Type,object>();
public void set_X<T>(T x)
{
xDict[typeof(T)] = x;
}
public T get_X<T>()
{
return (T)xDict[typeof(T)];
}
}
Why you would want to is an entirely different matter, though. It generally makes more sense to start with something you want to do than some way you want to do it.