It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
I was playing with different techniques for deep object cloning in C#, and finally came to pretty elegant solution that uses reflection and is applicable for non-serializable types. I am just wondering is there something wrong with it, and if anybody has comments or use case that does not work with this approach. Here is the code. Thanks for comments!
public static T Clone<T>(this T source)
{
// Get the type
Type type = source.GetType();
T clone = (T)Activator.CreateInstance(type);
// Loop through the properties
foreach (PropertyInfo pInfo in type.GetProperties())
{
pInfo.SetValue(clone, pInfo.GetValue(source, null), null);
}
// Loop through the fields
foreach (FieldInfo fInfo in type.GetFields())
{
fInfo.SetValue(clone, fInfo.GetValue(source).Clone());
}
return clone;
}
There are several issues I can see:
You only copy public properties and fields
You don't clone the property value, you just copy it. This means it's not a deep clone on properties.
There are certain types which are not easily clonable (or should not be cloned at all) like streams or filehandles (or any unmanaged resource for that matter) - your method might run into trouble there.
Your method won't handle circular references.
Not all types have a parameterless constructor.
What if there is no accessible parameterless constructor?
What if there is an member object that can't be shared (a file handle, maybe)?
What about non-public members?
Why the need to create a one-size fits all solution to a problem that doesn't exist (you don't need to be able to deep clone everything!)?
Related
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 9 years ago.
I can define an extension method to determine if an object is null
public static bool IsNull(this object obj) {
if (obj == null)
return true;
else return false;
}
But I can also do this:
public static bool IsNull<T>(this T obj) {
if(obj == null)
return true;
else return false;
}
Both are being applied to every object. What's the purpose of this T? To further elaborate what type is being expected? If yes, why this: typeof(T) is possible? And what's the reason behind (this T obj) where T: int) (where) then? (this doesn't work anyway as pointed out by #MatthewWatson)
So many questions.
The T is a type argument for a Generic method.
See here for MSDN documentation about generics: http://msdn.microsoft.com/en-us/library/512aeb7t.aspx
It's not specifically to do with extension methods; it's just to do with generics.
T means generic. It means that the type is not known. By default its an object as everything is an object in .Net. But you can specialize T with where paradigm. For instance where T is IDisposable. Then your function will only apply to IDisposable types.
T historically means Type. It is used by convention to define generic (in C++ - template) paramteres.
In you example it is not necessay because any object in .NET infrastructure inherits base object.
But remember good old days of C++, when C# even wasn't introduced. C++ has only plain type without common parent (i.e. object). So developers was forced to use something to tell to compiler "here something will be substituted, actually I don't know what exactly, but later, at compile-time it will be clear. Do it for me, please".
Returning to notation, in MFC another prefix was used - C like CString.
UPD: You first example will not works because it is extension and null object has not any methods, even you IsNull.
UPD1: Do not read UPD above, the cake is lie.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
I've done a bit of research on this and it seems pretty impossible but none of the answers have been specific enough to my issue. I currently have a Stack<object> that I push objects of multiple different types to. Before I push them I box them to object so it accepts them. Is there any possible way of automatically unboxing the object to the original unboxed type?
You can use the extension method OfType<OneOfTheTypes>() to get only those objects of that specific types casted to the correct type.
You can not automatically convert an object to a variable with the compile time type of a compatible type of the runtime type the object has.
The type of a variable is a compile time type and if the content is not known by the compiler to be of that type at compile time. The compiler does not know what runtime type each object in your stack actually has. You have to make a promise to the compiler (with a cast) that the runtime type will actually match the compile time type.
But to be frank. This kind of "check what type I have" is a typical smell of a bad design. Try to design your code with a common base class if you have similar types of objects or use different kinds of storage for different kind of objects.
There is no Automagic way to do it.
try this though
var objT = (T)Convert.ChangeType(obj, typeof(T));
var tuple = new Tuple<object, Type>(someObject, typeof(someObject));
stack.Push(tuple);
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 10 years ago.
Java and C# return type of methods are by reference or value? It's really confusing for me, need some explanation.
Thank you all.
In Java everything is returned by value. That includes references and here's where the confusion is!
If I have:
Trade t = new Trade();
then t is a reference (we'd say it is-a Trade, but that refers to the type. t really is a reference). When I return that from a method, I'm returning the reference, by value. The reference still points to that original object.
Hence if I return that t from a method and then invoke a further method on it, it invokes the method on the Trade that it originally pointed to.
C# can return results by either value or reference - it depends how you define the method.
Java can only ever return by value (or strictly speaking, return reference by value.)
As this little Memory Slogan goes in HeadFirst Book..
Roses are Red,
This poem is Choppy,
Passing By Value is
Passing By Copy.
In Java its always Value that is passed or returned.
Where as in C# it can return either by Reference or by Copy.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 11 years ago.
i have a list with: Circle, Triangle, Rectangle in it
i want to edit the element with the id X but list[X].radius; is not available because it is a child class.
You will have to detect the dynamic type of the element at runtime.
IShape value = list[x];
if(value is Circle)
{
((Circle)value).radius = 5;
}
You can also do something like:
Circle value = list[x] as Circle;
if(value != null)
{
value.radius = 5;
}
This has the advantage of being a bit faster, since the cast is only done once.
When you have a mixed list and want to access members defined for the derived types, you have to cast to the derived type.
((Circle)list[index]).Radius = 10; // alternately use is or as if you're unsure
Of course, by the virtue of simply having a mixed list, you're saying that you generally do not care about the differences between the derived types, you're content with using the base polymorphically. If you find yourself in a different position, you should perhaps rethink your strategy for storing or consuming these elements.
Typecast it:
((Circle)list[X]).Radius
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
I'm just asking this, because the same happened to me when trying to iterate over a DataRowCollection:
DataSet s;
...
foreach (var x in s.Tables[0].Rows)
{
//IntelliSense doesn't work here. It takes 'x' as an object.
}
I saw #Marc Gravell answer in Why is there no Intellisense with 'var' variables in 'foreach' statements in C#?, and now it's clear to me why this is happening.
I decided to take a look at the code of the DataRowCollection class, and GetEnumerator() is:
return this.list.GetEnumerator();
where list is a DataRowTree type that inherits the abstract class RBTree<K> (by the way, never knew there was an implementation of a Red-Black Tree in .NET before) which implements IEnumerable instead of IEnumerable<K>.
Is too hard to make RBTree<K> implement IEnumerable<K>? That would solve the main problem here.
I suppose it was developed like this in previous versions of .NET, but that doesn't really make sense anymore, does it?
My question is:
Is .NET old code updated in new releases? (for example, make DataRowCollection implement IEnumerable<DataRow> instead of IEnumerable)
Breaking changes, such as changing the class hierachy, is only implemented if there's a really good reason. In this case it's only for convinience.
An example of why it's a breaking change:
Let's say a project has these two methods.
public void Foo(object obj){
Console.WriteLine(obj.ToString();
}
public void Foo<T>(IEnumerable<T> obj){
throw new Exception();
}
now the change you want will make a program that has been recompiled but not changed throw an exception every time instead of printing to the console. It's not that it throws that's the problem but that the behaviour is different.
There's other ways such a change could break/alter a perfectly good program so the benefits (being able to write var in foreach loops) does not outweigh the cost (designing, implementing,testing,documenting), nor the potential costs of breaking customers work.