C# Defined Arrays - c#

Can I define an array such that the first element is String, the Second is an int and the third is a textbox?
It's like when we create a List we choose type of element List<string >
Update from Comment:
Sorry I couldnt explain.I need to like
this List<string,int,object> Firstly i
will set type and when i call the list
i will not need to cast
thanks

create list of objects. in C# everything is derived from object
List<object> list = new List<object> {"first", 10, new TextBox()};
EDIT(To comment):
Then you should create seperate class to hold those three items , or use Tuple
List<Tuple<string,int,TextBox>> list;

You can declare an array of object and do that. You're talking about a mixed type array, right?
var arr = new object[] { "Hi", 42, 3.7, 'A' }

If you need an array that has elements without a common base-class other than object, then you're going to need an array of objects!
object[] myArray = new object[] { "Hi", 23, new TextBox() };
Note that this is not really something you should doing. If you need to associate disparate types like this, a class makes much more sense.

You want a Tuple<string,int,TextBox>, not an array.

IMHO the best way to do this is through a List<> of objects:
String s = "hey!";
int i = 156;
TextBox t = new TextBox();
List<object> list = new List<object>(3);
list.Add(s);
list.Add(i);
list.Add(t);
The reason this works is because (almost?) everything in C# derives from the base-class object

Arrays are typically homogeneous collections, which means that every object contains in the array is of the same type (or at least shares a common parent type). An array of [string, int, textbox] could be defined as an object[] but that's really misuse of arrays.
Just create a proper class which contains the 3 fields.
class MyType {
public string myString;
public int myInt;
public Listbox myListbox;
}

If you're looking make a list of string, int, textbox, you can either create a class which has those members or look at the Tuple class in .net 4.0
List<Tuple<string,int,TextBox>

Define a class that contains the 3 types then define an array that contains the new type.

Object[] myObjects = new Object(){"myString", 42, textbox1};

System.Collections.Generic.Dictionary<string, object> source = new System.Collections.Generic.Dictionary<string, object>();
source.Add("A", "Hi");
source.Add("B", 10);
source.Add("C", new TextBox());
While accessing
string str = Convert.ToString(source["A"]);
int id = Convert.ToInt16(source["B"]);
TextBox t = (TextBox)source["C"];

I will suggest that you create a Type such as
enum ItemType { Int, String, Textbox }
class MyType {
public object objValue;
public ItemType itemType;
}
List<MyType> list = new List<MyType>();
.......
You can iterate through the list or extract the list by type such as below.
var intList = list.Where(e=>e.itemType == ItemType.Int);
Of course you can achieve the above with the enum and using the reflected Type info directly from the object, but I just think it is clearer this way also more explicitly list out the type your list can hold rather than just all type in the CLR

Related

creating a generic collection of key and values in C# 4.0

I need something like Dictionary where dynamic can be anything from string to objects.
But when i use objects, i need to know the type of the object and then access the appropriate properties of those objects.
Is there a way WITHOUT using Reflection.
* EDITED **
I tried to use this :
CloneObject<T, TU>(IDictionary<T, TU> sourceObject)
But if i use this, how can i access T's public fields without using reflection
You can use Hashtable for this purpose
Here is the Examples
http://www.dotnetperls.com/hashtable
You can also use Dictionary which is more efficient than Hashtable
See Examples Here:
http://www.dotnetperls.com/dictionary-keys
I'm confused a little bit. You trying to store any types of objects in your dictionary but access to them without reflection.
If so you can use dynamic types:
Dictionary dict = new Dictionary();
dict["string"] = "some string";
dict["int"] = 25;
dict["my_class"] = new MyClass {SomeProperty = 12};
And then you can access all this values without any casts:
string s1 = dict["string"].Substring(0, 4); // s1 equals to "some"
int propertyValue = dict["my_class"].SomeProperty; // propertyValue equals to 12
where MyClass is:
class MyClass
{
public int SomeProperty {get;set;}
}
Without using reflection, this task cannot be completed. All I have done is create clones of objects separately and then used them.

C# Dynamic Cast with Reflection and Lists

since yesterday i'm working on a problem and i don't get it yet...
I've got a class with many Methods and decide in Runtime wich Method has to be called. Every of this Methods returns a List with Elements from my Businessobjects.
My Class looks this way:
public class ReflectiveClass {
public List<BO1> DoSomethingWithBO1(int param){
List<BO1> list = new List<BO1>();
//....
return list;
}
public List<BO2> DoSomethingWithBO2(int param){
List<BO2> list = new List<BO2>();
//....
return list;
}
public void Process(){
//...get MethodInfo and so on
List<object> myReturnValue = (List<object>)methodInfo.Invoke(this, new object[]{param});
// here comes the Exception
}
}
So, at Invoking the Method i got a
InvalidCastException
and the Debugger told me he could not Cast from
System.Collections.Generic.List`1[BO1]
to
System.Collections.Generic.List`1[System.Object]
I wonder why this doesn't work. I thougt if i use a List every Object could be in this List.
I've even tried it with List but same behaviour.
Is it possible to read reflective the Type of the Return-Value of a Method? And can i then create a Generic List with this Returnvalue and cast to this List? This would be wonderfull.
Greetings and many Thanks for your Help!
Benni
Obviously BO1 derives from Object, and you can't cast List<Derived> to List<Base>. Suppose we have:
List<Apple> apples = AListOfApples();
List<Fruit> fruits = (List<Fruit>)apples; //suppose it's valid to cast
fruits.Add(new Orange()); //Of course we can add an Orange to the list of Fruit
//Now you can see the list of Apple has an Orange in it!!
You can use IEnumerable<T> instead.
If you have behaviour that changes and is determined at runtime, it's ideal for the Strategy pattern. Have a look at http://www.dofactory.com/Patterns/PatternStrategy.aspx
List<_> needs to be invariant to be statically type-safe. Imagine this compiled
var strlist = List<string> { "blub" };
var olist = (List<object>)strlist;
Up to this point everything is nice and dandy, but if you now tried to write to
the list like so
olist.Add(3);
the runtime would have to throw an exception as the underlying array is not an int array, but a string array. That's why it does not compile in the first place.
Note that contary to generic lists, arrays have been covariant since C# 1.0,
probably for Java compatibility. So this indeed compiles:
string[] strlist = new[] { "huhu" };
var olist = (object[])strlist;
olist[0] = 3;
... but throws an exception at runtime.
IEnumerable<out T> is covariant in T in C# 4.0 (therefore the out). Maybe this would be the more appropriate interface for your purposes.
You can use this :
object myReturnValue = mi.Invoke(this, new object[] { });
MethodInfo miToList = typeof(Enumerable).GetMethod("ToList");
MethodInfo miListObject = miToList.MakeGenericMethod(new[] { typeof(object) });
List<object> listObject = (List<object>)miListObject.Invoke(myReturnValue, new object [] { myReturnValue });
You should really split your class into two different classes, that should implement same interface. Using reflaction here is not a good thing.
Or if you methdods differ only in type of input parameters, make them generic.
Well the only solution is to create a new list..
public void Process(){
//...get MethodInfo and so on
List<object> myReturnValue = new List<object>(((IList)methodInfo.Invoke(this, new object[]{param})).ToArray());
// here comes no Exception!
}
I appreciate all the Answers!
For your information: I've implemented the Strategy Pattern, because it fits really good to my Project.
PS: I love this community, the peoble here help you so quick and with good solutions. Thanks!

How to declare a class dynamically? C#

is there any possibility to declare a class dynamically?
is there any possibility to create generic list with anonymous class in C#?
any code snippets will help. thanks
Declaring a class dynamically requires CodeDom.
is there any possibility to create generic list with anonymous class in C#?
Yes, but it's, in general, not recommended for use outside of the immediate context. For example, this creates a generic list of an anonymous type:
var range = Enumerable.Range(0, 100);
var genericList = range.Select(value => new { Value = value }).ToList();
In the above code, genericList is a List<T> containing an anonymous type.
As SLaks mentioned in the comments, it is possible. But it is non-trivial. I'm not sure what you are trying to do, but you can easily add anonymous types to a generic list of objects.
List<object> list = new List<object>();
for(int i = 0; i < 10; i++){
list.Add(new { SomeProperty = i, OtherProperty = "foobar" });
}
Microsoft made C# dynamic in version 4.0. You can use the new 'dynamic' keyword. The following link has some good examples of how to use the new dynamic type.
http://msdn.microsoft.com/en-us/library/dd264741.aspx

Multiple objects in list, C#

I'm looking for something similar to List<T>, that would allow me to have multiple T. For example: List<TabItem, DataGrid, int, string, ...> = new List<TabItem, DataGrid, int, string, ...>().
If you are using .NET 4, you could have a List<Tuple<T1, T2, ...>>
Otherwise, your choice is to implement your own type.
Create a class that defines your data structure, and then do
var list = new List<MyClass>();
Normally you'd just have List<MyClass> where MyClass had all those other ones as members.
If it can have any old type, then you need to use an ArrayList.
If you know ahead of time what you'll have in there, then you should either create your own structure, or use a Tuple.
Looks like you're after List<object>?
Tuples are best if you are using .net 4.0. But if you are working 3.5 or below, multidimensional object array is good. Here is the code. I have added 3 different types in a object array and I pushed the same to list. May not be the best solution for your question, can be achieved with object array and list. Take a look at the code.
class Program
{
static void Main(string[] args)
{
object[,] OneObject = new object[1,3]{ {"C Sharp",4,3.5 }};
List<object> MyList = new List<object>();
MyList.Add(OneObject);
object[,] addObject = new object[1,3]{{"Java",1,1.1}};
MyList.Add(addObject);
foreach(object SingleObject in MyList)
{
object[,] MyObject = (object[,])SingleObject;
Console.WriteLine("{0},{1},{2}", MyObject[0, 0], MyObject[0, 1], MyObject[0, 2]);
}
Console.Read();
}
}
Instead of trying in C# 4, you can give the old version features a chance here.
It seems you don't need a strongly typed collection here, in that case ArrayList is the best option.

Declaration of Anonymous types List [duplicate]

This question already has answers here:
A generic list of anonymous class
(22 answers)
Closed 8 years ago.
Is there any way to declare a list object of anonymous type. I mean
List<var> someVariable = new List<var>();
someVariable.Add(
new{Name="Krishna",
Phones = new[] {"555-555-5555", "666-666-6666"}}
);
This is because I need to create a collection at runtime.
How about dynamic?
List<dynamic> dynamicList = new List<dynamic>();
dynamicList.Add(new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } });
It involves a bit of hackery but it can be done.
static List<T> CreateListFromSingle<T>(T value) {
var list = new List<T>();
list.Add(value);
return list;
}
var list = CreateListFromSingle(
new{Name="Krishna",
Phones = new[] {"555-555-5555", "666-666-6666"}}
);
You can make a list like this, but you'll again have to use some serious hackery, and you'll have to use some "type by example" situations. For example:
// create the first list by using a specific "template" type.
var list = new [] { new { Name="", Phones=new[] { "" } } }.ToList();
// clear the list. The first element was just an example.
list.Clear();
// start adding "actual" values.
list.Add(new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } });
In general you can use the (arguably bad-smelling) cast by example trick others have mentioned to create instances of any generic type parameterized with an anonymous type for the type argument. However, for List<T> there is a slightly less gross way to do it:
var array = new[] {
new {
Name="Krishna",
Phones = new[] {"555-555-5555", "666-666-6666"}
}
};
var list = array.ToList();
Your sketch of a proposed syntax is similar to a feature we did not implement for C# 3 or 4, but we considered. We call the feature "mumble types", and it would go something like this:
List<?> myList = new List<?>() {
new {
Name="Krishna",
Phones = new[] {"555-555-5555", "666-666-6666"}
}
};
We call it "mumble types" because of course you'd read it "myList is a new list of hrmmf". :-)
The idea is that the compiler would look at the initializers and do its best to figure out what the type could possibly be, just the same way as how "var" means "look at the initializer and figure out what the type of the variable is". Whether we'd use "var" as the "mumble" or "?" (which is similar to what Java does in a related feature), or something else is an open question.
In any event, I wouldn't hold my breath waiting for this feature if I were you. It hasn't made the cut for several language versions so far, but it will stay on the list of possibilities for a while longer I think. If, hypothetically speaking, we were to be designing future versions of the language. Which we might or might not be. Remember, Eric's musings about future versions of C# are for entertainment purposes only.
Here's an approach that is somewhat cleaner than many of the other suggestions:
var list = Enumerable.Repeat(new { Name = "", Phones = new[] { "" } }, 0)
.ToList();
// ...
list.Add(new { Name = "Krishna",
Phones = new[] { "555-555-5555", "666-666-6666" } });
You can't make a collection of an anonymous type like this.
If you need to do this, you'll need to either use List<object>, or make a custom class or struct for your type.
Edit:
I'll rephrase this:
Although, technically, it's possible to make a list of an anonymous type, I would strongly recommend never doing this. There is pretty much always a better approach, as doing this is just making code that is nearly unmaintainable. I highly recommend making a custom type to hold your values instead of using anonymous types.
A custom type will have all of the same capabilities (since anonymous types are defined, by the compiler, at compile time), but will be much more understandable by the developer who follows you...
And just to play, too, here's my entry for "code I'd never actually want to use in the real world":
var customer = new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } };
var someVariable = new[]{1}.Select(i => customer).ToList();
I spent quite a lot of time trying to find a way to save myself some time using a list of anonymous types, then realised it was probably quicker just to use a private class inside the current class...
private class Lookup {
public int Index;
public string DocType;
public string Text;
}
private void MyMethod() {
List<Lookup> all_lookups = new List<Lookup> {
new Lookup() {Index=4, DocType="SuperView", Text="SuperView XML File"},
new Lookup() {Index=2, DocType="Word", Text="Microsoft Word Document"}
};
// Use my all_lookups variable here...
}
I don't think this is possible. Maybe in C# 4 using the dynamic keyword?

Categories

Resources