if class type list is there named
Collection<PurchaseOrderDetail> poDetails = new Collection<PurchaseOrderDetail>();
and another list with same type is there named _poH.PODetail
why _poH.PODetail = poDetails.ToList(); generates an error
Cannot implicitly convert type 'System.Collections.Generic.List'
to 'System.Collections.ObjectModel.Collection'
what is the solution for this, any explanation please.
All the reason behind the question is
_poH.PODetail = poDetails;
made poDetails.RemoveAt(Convert.ToInt32(e.RowIndex)); updates as well so I was searching for some thing like _poH.PODetail = poDetails.ToCollection();
According to the error message, _poH.PODetail is of type Collection, so assigning a list to it doesn’t work. But since poDetails is a collection itself, you can just assign it directly:
poH.PODetail = poDetails;
So you don’t actually need to call ToList() on it to convert it to a list.
There is no ToCollection method you could call on enumerables, but you could use the Collection constructor that takes a list to make it wrap that list and create a readonly collection:
new Collection(poDetails.ToList());
The short answer is simply that the ToList<T> extension returns an instance of List<T> class which, although similar, is not the same type as Collection<T>.
Basically this doesn't work for the same reasons you cannot set a string value to an integer variable.
One thing you can do though, is initializing the content of a new collection instance with an IList<T> instance. Therefore, the following should give you exactly what you want:
_poH.PODetail = new Collection(poDetails.ToList());
Also, as poke suggested, you might also want to assign the PODetail property with the poDetails variable itself.
_poH.PODetail = poDetails;
However, you must remember that Collection<T> is a reference type. This means that the objects in your collection won't be "copied" inside _poH.PODetail; instead, both poDetails and _poH.PODetail will be pointing to the exact same collection. Any changes done to one collection will automatically be reflected on the other.
I've come across the following C# syntax for the first time, I would have discarded it as a syntax error except that VS is absolutely happy with it and compiles.
var a = new ISomeInterface[0];
The interface is declared as
public interface ISomeInterface
{
}
Links to further reading are also highly appreciated.
You've created an array of ISomeInterface.
This is the same as declaring any other array, such as:
string[] a = new string[0];
I kinda did a double-take on that at first too, because at first glance it appeared the code was instantiating an interface, something you can't normally do.
It is creating a new array (zero-length), not a new instance of the interface. Incidentally, you can actually new an interface... under the right conditions ;p (COM attributes)
I noticed something in C# when dealing with custom objects that I found to be a little odd. I am certain it is just a lack of understanding on my part so maybe someone can enlighten me.
If I create a custom object and then I assign that object to the property of another object and the second object modifies the object assigned to it, those changes are reflected in the same class that did the assigning even though nothing is returned.
You want that in English? Here is an example:
class MyProgram
{
static void Main()
{
var myList = new List<string>();
myList.Add("I was added from MyProgram.Main().");
var myObject = new SomeObject();
myObject.MyList = myList;
myObject.DoSomething();
foreach (string s in myList)
Console.WriteLine(s); // This displays both strings.
}
}
public class SomeObject
{
public List<string> MyList { get; set; }
public void DoSomething()
{
this.MyList.Add("I was added from SomeObject.DoSomething()");
}
}
In the above sample I would have thought that, because SomeObject.DoSomething() returns void, this program would only display "I was added from MyProgram.Main().". However, the List<string> in fact contains both that line and "I was added from SomeObject.DoSomething()".
Here is another example. In this example the string remains unchanged. What is the difference and what am I missing?
class MyProgram
{
static void Main()
{
var myString = "I was set in MyProgram.Main()";
var myObject = new SomeObject();
myObject.MyString = myString;
myObject.DoSomething();
Console.WriteLine(myString); // Displays original string.
}
}
public class SomeObject
{
public string MyString { get; set; }
public void DoSomething()
{
this.MyString = "I was set in SomeObject.DoSomething().";
}
}
This program sample ends up displaying "I was set in MyProgram.Main()". After seeing the results of the first sample I would have assumed that the second program would have overwritten the string with "I was set in SomeObject.DoSomething().". I think I must be misunderstanding something.
This isn't odd, or strange. When you create a class, you create reference type. When you pass references to objects around, modifications to the objects they refer to are visible to anyone that holds a reference to that object.
var myList = new List<string>();
myList.Add("I was added from MyProgram.Main().");
var myObject = new SomeObject();
myObject.MyList = myList;
myObject.DoSomething();
So in this block of code, you instantiate a new instance of List<string> and assign a reference to that instance to the variable myList. Then you add "I was added from MyProgram.Main()." to the list referred to by myList. Then you assign a refernce to that same list to myObject.MyList (to be explicit, both myList and myObject.MyList are referring to the same List<string>! Then you invoke myObject.DoSomething() which adds "I was added from SomeObject.DoSomething()" to myObject.MyList. Since both myList and myObject.MyList are referring to the same List<string>, they will both see this modification.
Let's go by way of analogy. I have a piece of paper with a telephone number on it. I photocopy that piece of paper and give it to you. We both have a piece of paper with the same telephone number on it. Now I call up that number and tell the person on the other end of the line to put a banner up on their house that says "I was added from MyProgram.Main()." You call up the person on the other end of the line to put a banner up on their house that says "I was added from SomeObject.DoSomething()". Well, the person who lives at the house that has that telephone number is now going to have two banners outside their house. One that says
I was added from MyProgram.Main().
and another that says
I was added from SomeObject.DoSomething()
Make sense?
Now, in your second example, it's a little trickier.
var myString = "I was set in MyProgram.Main()";
var myObject = new SomeObject();
myObject.MyString = myString;
myObject.DoSomething();
You start by creating a new string whose value is "I was set in MyProgram.Main()" and assign a reference to that string to myString. Then you assign a reference to that same string to myObject.MyString. Again, both myString and myObject.MyString are referring to that same string whose value is "I was set in MyProgram.Main()". But then you invoke myObject.DoSomething which has this interesting line
this.MyString = "I was set in SomeObject.DoSomething().";
Well, now you've created a new string whose value is "I was set in SomeObject.DoSomething()." and assign a reference to that string to myObject.MyString. Note that you never changed the reference that myString holds. So now, myString and myObject.MyString are referring to different strings!
Let's go by analogy again. I have a piece of paper with a web address on it. I photocopy that piece of paper and give it to you. We both have a piece of paper with the same web address on it. You cross out that web address and write down a different address. It doesn't affect what I see on my piece of paper!
Finally, a lot of people in this thread are yammering about the immutability of string. What is going on here has nothing to do with the immutability of string.
It's absolutely correct:
myObject.MyList = myList;
This line assign a reference of myList to the myObject's property.
To prove this this, call GetHashCode() on myList and on myObject.MyList.
we are talking about different pointers to same memory location, if you wish.
Whether or not a method returns something, has nothing to do with what happens inside it.
You seem to be confused regarding what assignment actually means.
Let's start from the beginning.
var myList = new List<string>();
allocates a new List<string> object in memory and puts a reference to it into myList variable.
There is currently just one instance of List<string> created by your code but you can store references to it in different places.
var theSameList = myList;
var sameOldList = myList;
someObject.MyList = myList;
Right now myList, theSameList, sameOldList and someObject.MyList (which is in turn stored in a private field of SomeObject automagically generated by compiler) all refer to the same object.
Have a look at these:
var bob = new Person();
var guyIMetInTheBar = bob;
alice.Daddy = bob;
harry.Uncle = bob;
itDepartment.Head = bob;
There is just one instance of Person, and many references to it.
It's only natural that if our Bob grew a year older, each instance's Age would have increased.
It's the same object.
If a city was renamed, you'd expect all maps to be re-printed with its new name.
You find it strange that
those changes are reflected in the same class that did the assigning
—but wait, changes are not reflected. There's no copying under the hood. They're just there, because it's the same object, and if you change it, wherever you access it from, you access its current state.
So it matters not where you add an item to the list: as long as you're referring to the same list, you'll see the item being added.
As for your second example, I see Jason has already provided you with a much better explanation than I could possibly deliver so I won't go into that.
It will suffice if I say:
Strings are immutable in .NET, you can't modify an instance of string for a variety of reasons.
Even if they were mutable (like List<T> that has its internal state modifiable via methods), in your second example, you're not changing the object, you're changing the reference.
var goodGuy = jack;
alice.Lover = jack;
alice.Lover = mike;
Would alice's change of mood make jack a bad guy? Certainly not.
Similarly, changing myObject.MyString doesn't affect local variable myString. You don't do anything to the string itself (and in fact, you can't).
You are confusing both type of objects.
A List is a List of type string .. which means it can take strings :)
When you call the Add method it adds the string literal to its collection of strings.
At the time you call your DoSomething() method, the same list reference is available to it as the one you had in Main. Hence you could see both strings when you printed in the console.
Don't forget, that your variables are objects too. In the first example, you create a List<> object and assign it to your new object. You only hold a reference to a list, in this case, you now hold two references to the same list.
In the second example you assign a specific string object to your instance.
Alex - you wrote -
In the above sample I would have thought that, because SomeObject.DoSomething() returns void, this program would only display "I was added from MyProgram.Main().". However, the List in fact contains both that line and "I was added from SomeObject.DoSomething()".
This is not the case. The VOID of the function just means the function does not return a value. This has nothing to do with the this.MyList.Add method you are invoking in the DoSomething() method. You do have to references to the same object - myList and the MyList in the SomeObject.
This is how reference types behave and is expected. myList and myObject.MyList are references to the same List object in heap memory.
In the second example strings are immutable and are passed by value, so on the line
myObject.MyString = myString;
The contents of myString are copied to myObject.MyString (i.e. passed by value not by reference)
String is a bit special because it is a reference type and a value type with the special property of immutability (once you have created a string you can't change it only make a new one, but this is somewhat hidden from you by the implementation)
In the first example ... you are working with an mutable objects, and it is always accessed by reerence. All references to MyList in different objects refer to the same thing.
In the other case, strings behave a bit differently. Declaring a string literal (i.e. text between quotes) creates a new instance of a String, completely separated from the original version. You CAN NOT modify a string, just create a new one.
UPDATE
Jason is right, it has nothing to do with String immutability ... but ....
I can't help but think that string immutabiity has its word in here. Not in THIS concrete example, but if SomeObject.DoSomething's code was this : this.MyString += "I was updated in SomeObject.DoSomething()."; , then you would have to explain that new String is created by the "concatenation", and the first string is not updated
I have a list, defined as a global in the base class:
private List<Object> progObjs;
In the constructor of a derived class I have:
Object newObj = new Object();
this.progObjs = new List<Object>();
this.progObjs.Add(newObj);
Adding a break point after this shows that the object has gone into the list, and the list is of now Count = 1.
However, in another function in the class, I attempt to use the first object in the list (i.e. progObjs[0]), but it throws a NullReferenceException and the list is actually Count = 0, even though I haven't removed the object from the list myself.
What has happened to the object in my list?
Thanks,
Mitch.
Found the problem:
I'm working with XNA, and the base class's Initialize method was resetting the list after the derrived class defined it.
I am trying to call a class method dynamically depending on a condition. This is how I am doing it
I have three classes implement a single interface
interface IReadFile
{
string DoStuff();
}
The three classes A,B,C implement the interface above.
I am trying to add them to a hashtable with the code below
_HashT.Add("a", new classA());
_HashT.Add("b", new classB());
_HashT.Add("c", new classC());
This compiles fine, but gives a runtime error.{Object reference not set to an instance of an object.}
I was planning to return the correct class to the interface type depending on a parameter that matches the key value. say if I send in a. ClassA is returned to the interface type and the method is called.
IReadFile Obj = (IReadFile )_HashT["a"].GetType();
obj.DoStuff();
How do I correct the part above where the objects need to be added to the hashtable? Or do I need to use a different approach? All the classes are in the same assembly and namespace.
Thanks for your time.
As a guess, you have not instantiated your _HashT object.
You need somewhere in your code (declaration or constructor probably) to instantiate it:
HashTable _HashT = new HashTable();
If you do not do this, _HashT will be null and an attempt to add to it will fail with a NullReferenceException as you have been getting.
It appears you are seeing a NullReferenceException. Based on the limited code you provided I would say it is likely that the _HashT variable is not assigned. It could be possible that the exception is being generated from one of your class constructors as well.
If you use Dictionary<> you can use the following code to add and extract objects from the hashtable.
var hashtable = new Dictionary<IReadFile>();
hashtable.Add("a", new ClassA());
hashtable.Add("b", new ClassB());
hashtable.Add("c", new ClassC());
IReadFile obj = hashtable["a"];
obj.DoStuff();
Following your approach, you do not need to call GetType() on the value you pull out of _HashT. The value should already be an object of type IReadFile.
Why are you calling GetType? The IReadFile object is the thing you are putting in the hash. Casting a Type object into a IReadFile is not going to cast correctly.