How best to represent form fields in C# - c#

I'm starting to learn C# for WP7, I'm making an app to scrape various sites and display a couple of items of info off the page.
I'm going to allow the user to create multiple "accounts" on the phone - each is a set of login details for a particular site. For example, if I was to use stackoverflow as an example, I'd have a class:
public abstract class MyBaseClass
{
public Dictionary<string, string> fields;
}
public class StackOverflow : MyBaseClass
{
public StackOverflow()
{
fields.Add("Username", "Default Username");
fields.Add("Password", "");
}
}
The class will do all the work, I want people to be able to submit new classes for inclusion in later releases.
The application will iterate over each of the fields, displaying the appropriate form field to the user. Once completed, the UI will update the dictionary, ready to start scraping.
Using a dictionary seemed ok to start, but I hadn't thought about how to represent the data type - I want to define whether the input should be text, number, or password.
How would I best include that data?

Given that screen-scraping is bad at best and disasterous at worst, I must recommend that you only include sites (or serviecs) that provide a public documented API and then use that reference to define the data types that you are storing.
That said, if you're on C#/.NET 4 you might want to use the Tuple data type.

One thing to keep in mind with this pattern is that pretty much everything you do with this object is based on a "magic string". String data has very little that can be checked at compile-time; a field name referenced as a string may have a spelling mistake that would be caught immediately by the compiler; similarly, setting "ABC123" as a field that was supposed to be a decimal is just fine 'til you try and parse it out.
If you're determined to go down this path, I would change the Dictionary to a List of a custom class that contained all the metadata of the field; its name, its type, current value, etc. The list should be protected, and accessed via one or more indexers on the class that derives from your MyBaseClass class, which can pull data based on an index position OR by field name, as the situation may call for.
Be aware that in changing to a List, the naive implementation would result in a linear search time for a field, while a Dictionary gives you logarithmic access time. You can mitigate this by sorting the list and implementing a BinarySearch to find field names.

You are going to have to create your own model to represent this. Just do what comes naturally and makes sense. How about this:
public enum InputType
{
Text,
Number,
Password
}
public class Value
{
public object Value { get; set;}
public InputType InputType { get; set;}
}
public abstract class MyBaseClass
{
public Dictionary<string, Value> fields;
}
public class StackOverflow : MyBaseClass
{
public StackOverflow()
{
fields.Add("Username", new Value() {
Value = "Default Username",
InputType = InputType.Text
});
fields.Add("Password", new Value() {
Value = "hw78fksm9",
InputType = InputType.Password
});
}
}
By the way, don't make the fields variable of MyBaseClass public, this is an implementation detail and should be hidden / encapsulated!

Related

Define Type As Copy of Another with Different Data Types

I'm trying to find a way to define a class such that it has the same properties as another class, but with different property types (all strings), without having to enumerate the properties, and such that you can reference the properties via code rather than by a string key.
For clarification, below is an example of the functionality of what I am looking for...
public class ValuedClass
{
public int Value {get; set;}
}
public class StringedClass : Stringified<ValuedClass> {}
public class Program
{
public static void Main(int[] args)
{
var valued = new ValuedClass() { Value = 5 };
var stringed = new StringedClass() { Value = "taco" };
}
}
I've messed around with abstract classes w/ type arguments for each data type (ie. TNumber, TMoney, TDate, etc.), a Stingified with this[string propName] defined, making everything object types, and other solutions, but each one requires enumerating the properties again (thus giving another update failure point), or adds an unacceptable level of complexity to the code.
At this point, I'd think that I'd have to hijack how .net handles the code when you type valued.Value, and tell it to then go to this["Value"], but I haven't been able to find any way to do something like that either.

Object Oriented - Class Variables

I am pretty new to OOP and looking into things in a bit more depth, but I have a bit of confusion between these 3 methods in C# and which one is best and what the differences are between 2 of them.
Example 1
So lets start with this one, which (so I understand) is the wrong way to do it:
public class MyClass
{
public string myAttribute;
}
and in this way I can set the attribute directly using:
myObject.myAttribute = "something";
Example 2
The next way I have seen and that seems to be recomended is this:
public class MyClass
{
public string myAttribute { get; set;}
}
With getters and setters, this where I dont understand the difference between the first 2 as the variable can still be set directly on the object?
Example 3
The third way, and the way that I understand the theory behind, is creating a set function
public class MyClass
{
string myAttribute;
public void setAttribute(string newSetting)
{
myAttribute = newSetting;
//obviously you can apply some logic in here to remove unwanted characters or validate etc.
}
}
So, what are the differences between the three? I assume example 1 is a big no-no so which is best out of 2 and 3, and why use one over the other?
Thanks
The second
public class MyClass
{
public string MyAttribute { get; set;}
}
is basically shorthand for:
public class MyClass
{
private string myPrivateAttribute;
public string MyAttribute
{
get {return myPrivateAttribute;}
set {myPrivateAttribute = value;}
}
}
That is an auto-implemented property, which is exactly the same as any regular property, you just do not have to implement it, when the compiler can do that for you.
So, what is a property? It's nothing more than a couple of methods, coupled with a name. I could do:
public class MyClass
{
private string myPrivateAttribute;
public string GetMyAttribute()
{
return myPrivateAttribute;
}
public void SetMyAttribute(string value)
{
myPrivateAttribute = value;
}
}
but then instead of writing
myClass.MyAttribute = "something";
string variable = myClass.MyAttribute;
I would have to use the more verbose, but not necessarily clearer form:
myClass.SetMyAttribute("something");
string variable = myClass.GetMyAttribute();
Note that nothing constraints the contents of the get and set methods (accessors in C# terminology), they are methods, just like any other. You can add as much or as little logic as you need inside them. I.e. it is useful to make a prototype with auto-implemented properties, and later to add any necessary logic (e.g. log property access, or add lazy initalization) with an explicit implementation.
What your asking here has to do with encapsulation in OOP languages.
The difference between them is in the way you can access the propriety of an object after you created an object from your class.
In the fist example you can access it directly new MyClass().MyAttribute whether you get or set it's value.
In the second example you declare 2 basic functions for accessing it:
public string MyAttribute
{
get {return myPrivateAttribute;}
set {myPrivateAttribute = value;}
}
In the third example you declare your own method for setting the value. This is useful if you want to customize the setter. For example you don't want to set the value passed, but the value multiplied by 2 or something else...
I recommend some reading. You can find something here and here.
Property is a syntactic sugar over private attribute with get and set methods and it's realy helpful and fast to type;
You may treat automatic property with { get; set;} as a public attribute. It has no additional logic but you may add it later without uset ever notice it.
Just exchange
public string MyLine { get; set;}
to
string myLine;
public string MyLine
{
get { return myLine; }
set { myLine = value + Environment.NewLine; }
}
for example if you need so.
You can also easily create read only property as { get; private set }.
So use Properties instead of public attributes every time just because its easier and faster to write and it's provides better encapsulation because user should not be used get and set methods if you decide to use it in new version of yours programm.
One of the main principles of OOP is encapsulation, and this is essentially the difference between the first example and the other 2.
The first example you have a private field which is exposed directly from the object - this is bad because you are allowing mutation of internal data from outside the object and therefore have no control over it.
The other 2 examples are syntactically equivalent, the second being recommended simply because it's less code to write. However, more importantly they both restrict access & control mutation of the internal data so give you complete control over how the data should be managed - this is ecapsulation.

what is the meaning of data hiding

One of the most important aspects of OOP is data hiding. Can somebody explain using a simple piece of code what data hiding is exactly and why we need it?
Data or Information Hiding is a design principal proposed by David Paranas.
It says that you should hide the
design decisions in one part of the
program that are likely to be changed
from other parts of the program, there
by protecting the other parts from
being affected by the changes in the
first part.
Encapsulation is programming language feature which enables data hiding.
However note that you can do data\information hiding even without encapsulation. For example using modules or functions in non Object Oriented programming languages. Thus encapsulation is not data hiding but only a means of achieving it.
While doing encapsulation if you ignore the underlying principal then you will not have a good design. For example consider this class -
public class ActionHistory
{
private string[] _actionHistory;
public string[] HistoryItems
{
get{return _actionHistory; }
set{ _actionHistory = value; }
}
}
This calls encapsulates an array. But it does not hide the design decision of using a string[] as an internal storage. If we want to change the internal storage later on it will affect the code using this class as well.
Better design would be -
public class ActionHistory
{
private string[] _actionHistory;
public IEnumerable<string> HistoryItems
{
get{return _actionHistory; }
}
}
I'm guessing by data hiding you mean something like encapsulation or having a variable within an object and only exposing it by get and modify methods, usually when you want to enforce some logic to do with setting a value?
public class Customer
{
private decimal _accountBalance;
public decimal GetBalance()
{
return _accountBalance;
}
public void AddCharge(decimal charge)
{
_accountBalance += charge;
if (_accountBalance < 0)
{
throw new ArgumentException(
"The charge cannot put the customer in credit");
}
}
}
I.e. in this example, I'm allowing the consuming class to get the balance of the Customer, but I'm not allowing them to set it directly. However I've exposed a method that allows me to modify the _accountBalance within the class instance by adding to it via a charge in an AddCharge method.
Here's an article you may find useful.
Information hiding (or more accurately encapsulation) is the practice of restricting direct access to your information on a class. We use getters/setters or more advanced constructs in C# called properties.
This lets us govern how the data is accessed, so we can sanitize inputs and format outputs later if it's required.
The idea is on any public interface, we cannot trust the calling body to do the right thing, so if you make sure it can ONLY do the right thing, you'll have less problems.
Example:
public class InformationHiding
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
/// This example ensures you can't have a negative age
/// as this would probably mess up logic somewhere in
/// this class.
private int _age;
public int Age
{
get { return _age; }
set { if (value < 0) { _age = 0; } else { _age = value; } }
}
}
Imagine that the users of your class are trying to come up with ways to make your class no longer fulfill its contract. For instance, your Banking object may have a contract that ensures that all Transactions are recorded in a log. Suppose mutation of the Bank's TransactionLog were publically accessible; now a consuming class could initiate suspect transactions and modify the log to remove the records.
This is an extreme example, but the basic principles remain the same. It's up to the class author to maintain the contractual obligations of the class and this means you either need to have weak contractual obligations (reducing the usefulness of your class) or you need to be very careful about how your state can be mutated.
What is data hiding?
Here's an example:
public class Vehicle
{
private bool isEngineStarted;
private void StartEngine()
{
// Code here.
this.isEngineStarted = true;
}
public void GoToLocation(Location location)
{
if (!this.isEngineStarted)
{
this.StartEngine();
}
// Code here: move to a new location.
}
}
As you see, the isEngineStarted field is private, ie. accessible from the class itself. In fact, when calling an object of type Vehicle, we do need to move the vehicle to a location, but don't need to know how this will be done. For example, it doesn't matter, for the caller object, if the engine is started or not: if it's not, it's to the Vehicle object to start it before moving to a location.
Why do we need this?
Mostly to make the code easier to read and to use. Classes may have dozens or hundreds of fields and properties that are used only by them. Exposing all those fields and properties to the outside world will be confusing.
Another reason is that it is easier to control a state of a private field/property. For example, in the sample code above, imagine StartEngine is performing some tasks, then assigning true to this.isEngineStarted. If isEngineStarted is public, another class would be able to set it to true, without performing tasks made by StartEngine. In this case, the value of isEngineStarted will be unreliable.
Data Hiding is defined as hiding a base class method in a derived class by naming the new class method the same name as the base class method.
class Person
{
public string AnswerGreeting()
{
return "Hi, I'm doing well. And you?";
}
}
class Employee : Person
{
new public string AnswerGreeting()
{
"Hi, and welcome to our resort.";
}
}
In this c# code, the new keyword prevents the compiler from giving a warning that the base class implementation of AnswerGreeting is being hidden by the implementation of a method with the same name in the derived class. Also known as "data hiding by inheritance".
By data hiding you are presumably referring to encapsulation. Encapsulation is defined by wikipedia as follows:
Encapsulation conceals the functional
details of a class from objects that
send messages to it.
To explain a bit further, when you design a class you can design public and private members. The class exposes its public members to other code in the program, but only the code written in the class can access the private members.
In this way a class exposes a public interface but can hide the implementation of that interface, which can include hiding how the data that the class holds is implemented.
Here is an example of a simple mathematical angle class that exposes values for both degrees and radians, but the actual storage format of the data is hidden and can be changed in the future without breaking the rest of the program.
public class Angle
{
private double _angleInDegrees;
public double Degrees
{
get
{
return _angleInDegrees;
}
set
{
_angleInDegrees = value;
}
}
public double Radians
{
get
{
return _angleInDegrees * PI / 180;
}
set
{
_angleInDegrees = value * 180 / PI;
}
}
}

Should I use public properties and private fields or public fields for data?

In much of the code I have seen (on SO, thecodeproject.com and I tend to do this in my own code), I have seen public properties being created for every single private field that a class contains, even if they are the most basic type of get; set; like:
private int myInt;
public int MyInt
{
get { return myInt; }
set { myInt = value }
}
My question is: how does this differ from:
public int MyInt;
and if we should use properties instead of public fields why should we use them in this specific case? (I am not talking about more complex examples where the getters and setters actually do something special or there is only one get or set (read/write only) rather than just returning/setting a value of a private field). It does not seem to add any extra encapsulation, only give a nice icon in IntelliSense and be placed in a special section in class diagrams!
See this article http://blog.codinghorror.com/properties-vs-public-variables/
Specifically
Reflection works differently on variables vs. properties, so if you rely on reflection, it's easier to use all properties.
You can't databind against a variable.
Changing a variable to a property is a breaking change.
Three reasons:
You cannot override fields in subclasses like you can properties.
You may eventually need a more complex getter or setter, but if it's a field, changing it would break the API.
Convention. That's just the way it's done.
I'm sure there are more reasons that I'm just not thinking of.
In .Net 3.x you can use automatic properties like this:
public int Age { get; set; }
instead of the old school way with declaring your private fields yourself like this:
private int age;
public int Age
{
get { return age; }
set { age = value; }
}
This makes it as simple as creating a field, but without the breaking change issue (among other things).
When you create private field name and a simple public property Name that actually gets and sets the name field value
public string Name
{
get { return name; }
}
and you use this property everywhere outside your class and some day you decide that the Name property of this class will actually refer to the lastName field (or that you want to return a string "My name: "+name), you simply change the code inside the property:
public string Name
{
get { return lastName; //return "My name: "+name; }
}
If you were using public field name everywhere in the outside code then you would have to change name to lastName everywhere you used it.
Well it does make a difference. Public data can be changed without the object instance knowing about it. Using getters and setters the object is always aware that a change has been made.
Remember that encapsulating the data is only the first step towards a better structured design, it's not an end-goal in itself.
You have to use properties in the following cases:
When you need to serialize data in the property to some format.
When you need to override properties in derived class.
When you implement get and set methods with some logic. For example, when you implement Singleton pattern.
When you're derived from interface, where property was declared.
When you have specific issues related to Reflection.
It... depends?
I always use getters & setters, since they created this shortcut:
public int Foo { get; set; }
At compile time it is translated. Now you can't get fancy with it, but it is there, and if you need to get fancy you just spell it out later.
However public, private, protected... it's all a matter of who you want to be able to tweak the data. We use inheritance a lot and this is a very common method for us, so that only chidren can edit certain properties.
protected _foo;
public Foo
{
get { return _foo; }
} //lack of set intentional.
I can't believe that with 11 answers, nobody has said this:
Not all private fields should be exposed as public properties. You should certainly use properties for anything that needs to be non-private, but you should keep as much of your class private as possible.
There are many reasons why.
Mainly:
You can do some other functions when the variable is set
You can prevent setting and provide only get
Some 'things' only work on properties (DataBinding, for example)
You can hide the implementation of the property [perhaps it is a ViewState variable, in ASP.NET).
The point is - what if further down the line you want to make sure that every time myInt is referenced something special happens (a log file is written to, it's changed to 42 etc)? You can't do that without getters and setters. Sometimes it's wise to program for what you might need, not what you need right now.
Actually, if you're using Silverlight, you'll realise that fields cannot be set a static resources and thus you'll have to use a property (even to access a const).
I've realised that when I tried to federate the region names I use in Composite Guidance (PRISM).
However, that's just a language limitations and apart from static/const fields I alsways use properties.
The idea is you should not accidentally/unintentionally change the value of a class private field outside.
When you use get and set, that means you are changing the class private field intentionally and knowingly.
Setting a value into a private field only changes that field,but making them in property you can handle another arguments for example,you can call a method after setting a value
private string _email;
public string Email
{
get
{
return this._email;
}
set
{
this._email = value;
ReplaceList(); //**
}
}
In simpler words, answer to your question is the access modifiers i.e. public and private.
If you use:
public int myInt;
public int MyInt
{
get { return myInt; }
set { myInt = value }
}
then both MyInt property and myInt variable is available in the project to be modified.
Means, if your class suppose A is inherited by class suppose B,
then myInt and MyInt both are available for modification and no check can be applied.
Suppose you want myInt value can be set in derive class if some particular condition pass.
This can be achieved only by making field private and property to be public.
So that only property is available and conditions can be set based on that.

C# Generic List of Generic List of Multiple Types

Here is an abstraction and simplification of my issue:
I have a set of toys and a corresponding box for these toys. I want the user to be able to specify the largest type of toy that the box can hold:
public class Box<T> {}
then within the Box class I want to have a generic list of toys, but each toy contained within the box will have a generic type:
public class Box<T>
{
public List<Toy> = new List<Toy>();
public bool Whatever;
[member functions, constructors...]
[The member functions will depend on T]
}
The Toys class will look like this:
public class Toy<T> where T : struct //T is any type
{
public List<T> = new List<T>();
public string Name;
public string Color;
[member functions, constructors...]
}
I want to be able to create Toys with many different types and then insert them into a Box with another specified type. Then I'd like to be able to add boxes together returning a Box with the largest type.
I really don't know how to begin. The list of a generic class with multiple types is really throwing me for a loop. I read various articles about using an abstract class or an interface, but haven't found an example or anything that accomplishes something similar to what I'm trying to do.
Any assistance anybody could provide would be very appreciated.
The solution can be in C# 4.0.
Possible Future Clarification:
I want Toy to be generic and accept a argument at instantiation because Toy must also have a List as a member.
The nested List within Toy is my main problem. I then want a list within Box that holds Toys, but each toy has as different type constructor.
Update:
I fixed the Box to Box that was a typo.
Update 2:
Toy<plastic> tyPlastic = new Toy<plastic>("Name1", Blue, new plastic[] {0xFFEE00, 0xF34684, 0xAA35B2});
Toy<wood> tyWood = new Toy<wood>("Name2", Grain, new wood[] {a1, f4, h7});
Box<plastic> bxBox = new Box<plastic>();//The Box has the ability to hold both plastic and wood toys. Plastic > Wood > Paper
Final: I ended up removing the requirement for Box to be generic. I then used reflection to create dynamically typed Toy. Thanks everybody.
The code you're building will be best understood if it models reality well.
The way to model "an A of B" is to use generics. A set of kinds of box that can hold one kind of thing would be modelled as Box<T>. A box that can only hold toys would be Box<Toy>. A set of kinds of box that can hold one kind of thing, and that thing has to be a toy would be a Box<T> where T : Toy.
So far so good. But the concept of Toy<T> doesn't map to anything in real life. You might have a box of biscuits or a box of toys, but you don't have a toy of biscuits, a toy of dolls or a toy of giraffes. The concept "toy of" doesn't make any sense, so don't model it.
A more sensible thing to model would be "there is a general class of things called toys. There is no one thing that is just a toy; every toy is a more specific kind of toy. A ball is a toy. A doll is a toy." So model that:
abstract class Toy {}
class Doll : Toy {}
class Ball : Toy {}
You said
I want Toy to be generic and accept a argument at instantiation because Toy must also have a List as a member.
Why? A toy does not have a list of things. So don't model that. Rather, a box is logically modelled as a list of the toys that are inside the box. (Or, since a box does not generally apply an ordering, and a box contains only unique toys, perhaps a set of toys would be better.)
I want to be able to create Toys with many different types and then insert them into a Box with another specified type.
OK. So an operation on Box<T> is void Insert(T item). You can put a toy into a box of toys, you can put a doll into a box of dolls, but you cannot put a ball into a box of dolls.
Then I'd like to be able to add boxes together returning a Box with the largest type.
You need to more carefully define "the largest type". If you add a box of dolls to a box of balls, clearly the result is neither a box of balls nor a box of dolls. The result is a box of toys.
Here's how I would model this. We already have the toy hierarchy. I would continue by saying that a box of T is implemented as a set of its contents, and provides a sequence of its contents.
// Haven't actually compiled this.
class Box<T> : IEnumerable<T>
{
private HashSet<T> set = new HashSet<T>();
public Insert(T item) { set.Add(item); }
public IEnumerator<T> GetEnumerator() { return set.GetEnumerator(); }
public IEnumerator IEnumerable.GetEnumerator() { return this.GetEnumerator(); }
All very boring so far. Now we come to the interesting bit. This only works well in C# 4.
public static Box<T> MergeBoxes(IEnumerable<T> box1, IEnumerable<T> box2)
{
Box<T> box = new Box<T>();
foreach(T item in box1) box.Insert(item);
foreach(T item in box2) box.Insert(item);
return box;
}
}
Now you can say
Box<Doll> dollbox = new Box<Doll>() { new Doll() };
Box<Ball> ballbox = new Box<Ball>() { new Ball() };
Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox, dollbox);
The result of merging a box of dolls with a box of balls is a box of toys.
This last bit only works because IEnumerable<T> is covariant in C# 4. In C# 3, this would be trickier to get right; you'd have to do something like:
Box<Toy> toybox2 = Box<Toy>.MergeBoxes(ballbox.Cast<Toy>(), dollbox.Cast<Toy>());
Does that make sense?
I'm not sure if this is what you actually want to do, since it is a bit hackish. If you want lists of every conceivable toy type, including ones Box might not know about, you're going to need to use your generic parameters to filter out the correct toys. I don't recommend doing this unless the Box is just a blank slate for stuffing common things into (eg. a BlackBoard).
For example, you could have just one List<Object> and all the methods check if the contents are of the correct type before manipulating them. You could also use a Dictionary<Type, Object> in order to skip the term-by-term filtering step, but cause some problems with inheritance (the list of animals wouldn't include things added to the list of giraffes).
Here is a simple implementation of the Dictionary approach:
public class MultiGenericList
{
private readonly Dictionary<Type, Object> map = new Dictionary<Type,Object>();
public List<T> GetList<T>()
{
if (!this.map.ContainsKey(typeof(T))) this.map.Add(typeof(T), new List<T>());
return (List<T>)this.map[typeof(T)];
}
}
You can adapt this code to restrict the lists to be of a specific type, and you can adapt it further so you can join lists which share a common base type. That might look like this:
MultiGenericList<T> Join<C1, C2, T>(MultiGenericList<C1> child1,
MultiGenericList<C2> child2) where C1 : T, C2 : T
{
...
}
I quote MSDN:
Generic classes encapsulate operations
that are not specific to a particular
data type. The most common use for
generic classes is with collections
like linked lists, hash tables,
stacks, queues, trees and so on where
operations such as adding and removing
items from the collection are
performed in much the same way
regardless of the type of data being
stored.
Given your description, the closest object to which that would be applicable would be Box, but then again, you know its going to contain Toys, and has a maximum ToySize, and that Toys have a type (Ball, Horse...). I might be wrong here, but going with generics might not really be necessary. I'm thinking something like :
public class Box
{
public ToyType MaxType { get; set; }
public List<Toy> Toys = new List<Toy>();
public void Add(Toy toy)
{
if (toy.Type.Size <= MaxType.Size) //if its not larger, or whatever compatibility test you want
Toys.Add(toy);
}
}
public class Toy
{
public ToyType Type { get; set; }
public Toy(ToyType type)
{
Type = type;
}
}
public abstract class ToyType
{
public abstract string TypeName { get; set; }
public abstract int Size { get; set; }
}
Unless you have a particular reason behind using generics.
I had this problem when constructing a list of generic types that I didn't know the generic part of at compile time, they needed to be dynamic somehow.
I solved my problem by having the generic class like this:
public class MyGenericType<T>
{
public T Data;
public string SomeString;
}
And then instantiating and using that class as follows;
List<MyGenericType<dynamic>> myList = new List<MyGenericType<dynamic>>();
myList.Add(new MyGenericType<dynamic>(){ Data = "my string" });
myList.Add(new MyGenericType<dynamic>(){ Data = null });
myList.Add(new MyGenericType<dynamic>(){ Data = new EvenOtherType() });
WARNING:
You can access the members of the children, but they're not the same on all in the list! It'll let you compile it, but it might break during runtime!
For example, I have a "DoSomething()" method on my class "EvenOtherType". If I try to call that while looping over the list, obviously the string and the int versions will crash during runtime!
Be careful!
Your very last line "every toy has a different constructor" implies that you need either a Toy base-class, with each specific toy inheriting from that class:
public abstract class Toy{} // abstract base class
public class Ball : Toy
{
public Ball(){} // Ball constructor
}
or an interface to define the generic Toy, with each specific type of Toy implementing the interface... either the interface or base class can define the generic list.
The reason you need this is that if you use a single class for all types of Toy then you won't be able to alter the constructor based on the type... that's just not a behavior generics support.
public interface IToy {}
public class Toy<T>: IToy
{
public List<T> = new List<T>();
public string Name;
public string Color;
}
You can access every member (variable, method etc.) of the Toy via reflection.
Naturally if you define Getters and Setters, you can just use them in the interface as long as they don't use a generic type T.
List<IToy> toys = new List(IToy);
toys.Add(new Toy());
IToy toy = toys.get(0);
toy.GetType().GetField("Name").GetValue(toy);
This is probably a slower solution cpu-wise but you can access EVERY generic type right away. If the number of the types you want to access is low, you should use inheritance so that T is generalized by a concrete type (like material in your example).

Categories

Resources