HashSet(Of T) - how can I get elements by position number ?
-
"REM so "clone" actually is created as just an Object and not of the same type as "element" / "entity"
This is not true because I try to use this instruction :
Ctype(element,Child1)
--- and after that everything works correctly But as I have explained , I can't use this kind of cast because I don't have the type Child1. I have only the string "Child1". For that I try to use CTypeDynamic. So I want to know why this line :
System.Type.Gettype("Child1")
produce Nothing ? Because with default types like "Integer" is working.
dilkonika wrote:
This is not true because I try to use this instruction : --- and after that everything works correctly
If we don't misunderstand each other here, this is what I would expect because you're casting element to its actual type, so CopyEntity(..) will be called for the actual type, so
Dim clone As New T()
will not create clone as Object but as the same type as element. So this is essentially what I presented as your first option. The reason why Type.Gettype("Child1") doesn't work is because you have to specify more than just the name of the class, please refer to MSDN[^]. But CTypeDynamic(..) won't help you because it requires the requested target-type as a static type argument, which you don't have and won't get with Type.Gettype(..). So it's still option 1 or 2 :)If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
dilkonika wrote:
This is not true because I try to use this instruction : --- and after that everything works correctly
If we don't misunderstand each other here, this is what I would expect because you're casting element to its actual type, so CopyEntity(..) will be called for the actual type, so
Dim clone As New T()
will not create clone as Object but as the same type as element. So this is essentially what I presented as your first option. The reason why Type.Gettype("Child1") doesn't work is because you have to specify more than just the name of the class, please refer to MSDN[^]. But CTypeDynamic(..) won't help you because it requires the requested target-type as a static type argument, which you don't have and won't get with Type.Gettype(..). So it's still option 1 or 2 :)If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
as I have read ion this link https://msdn.microsoft.com/en-us/library/ee835926(v=vs.110).aspx[^] , the type specified as parameter inside CtypeDynamic , may be a variable. Inside this link there;s an example that use Gettype inside the CTypeDynamic. and for the type.Gettype , I read that I have to use the namespace together with my string;s name type. But where can I find the namespace for my entity object ?
-
as I have read ion this link https://msdn.microsoft.com/en-us/library/ee835926(v=vs.110).aspx[^] , the type specified as parameter inside CtypeDynamic , may be a variable. Inside this link there;s an example that use Gettype inside the CTypeDynamic. and for the type.Gettype , I read that I have to use the namespace together with my string;s name type. But where can I find the namespace for my entity object ?
dilkonika wrote:
the type specified as parameter inside CtypeDynamic
That version of CTypeDynamic(..) won't help you either because it returns Object.
dilkonika wrote:
But where can I find the namespace for my entity object ?
In the source file where it's declared? :confused: Alternatively by looking at entity.GetType().FullName[^] Why don't you try my suggested Reflection-approach?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
dilkonika wrote:
the type specified as parameter inside CtypeDynamic
That version of CTypeDynamic(..) won't help you either because it returns Object.
dilkonika wrote:
But where can I find the namespace for my entity object ?
In the source file where it's declared? :confused: Alternatively by looking at entity.GetType().FullName[^] Why don't you try my suggested Reflection-approach?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
For namespace I'm asking because I try to use the name where it was declared but doesn't work. In the link for Type.Gettype , I found that I need the AssemblyQualifiedName. Is this the namespace + the name of class ?? for this I'm confused.
On the page for Type.GetType are links to Type.AssemblyQualifiedName[^] where this is documented.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
On the page for Type.GetType are links to Type.AssemblyQualifiedName[^] where this is documented.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Yes , now I'm using this code :
Dim t a type
Dim s as string = "MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"
t=System.Type.GetType(s)But the problem is that the t get this value : "MyProg1.Child1" , I'm expecting to have just "Child1" What's the problem ?
-
Yes , now I'm using this code :
Dim t a type
Dim s as string = "MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"
t=System.Type.GetType(s)But the problem is that the t get this value : "MyProg1.Child1" , I'm expecting to have just "Child1" What's the problem ?
It's one and the same; unless you have multiple classes named "Child1" in your solution, then "Child1" may or may not be the same as "MyProg1.Child1".
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
It's one and the same; unless you have multiple classes named "Child1" in your solution, then "Child1" may or may not be the same as "MyProg1.Child1".
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Ok , but then why when I use :
CTypeDynamic(Element,Child1)
everything is ok with my CopyEntity function. Whe I use :
Dim t a type
Dim s as string = "MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"
t=System.Type.GetType(s)
CtypeDynamic(Element,t)I'm still getting the error :
An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: The entity type Object is not part of the model for the current context.
-
Ok , but then why when I use :
CTypeDynamic(Element,Child1)
everything is ok with my CopyEntity function. Whe I use :
Dim t a type
Dim s as string = "MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"
t=System.Type.GetType(s)
CtypeDynamic(Element,t)I'm still getting the error :
An unhandled exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll
Additional information: The entity type Object is not part of the model for the current context.
I'm trying to replicate it.. it's not actually CTypeDynamic(Element,Child1) how your working code looks like, is it? Is it CTypeDynamic(Element, GetType(Child1)) or CTypeDynamic<Child1>(Element) ?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
I'm trying to replicate it.. it's not actually CTypeDynamic(Element,Child1) how your working code looks like, is it? Is it CTypeDynamic(Element, GetType(Child1)) or CTypeDynamic<Child1>(Element) ?
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Sorry Friend. It's my mistake. Now it's confirmed : The CloneEntity Function is working correctly when I pass the element that I get from the expression :
Dim element = CType(Enumerable.ElementAt(CallByName(MyObj1, "Child1", CallType.Get), k), Child1)
But is not working correctly when I pass the element that I get from this expression :
Dim element = CTypeDynamic(Enumerable.ElementAt(CallByName(MyObj1, "Child1", CallType.Get), k), Type.GetType("MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"))
-
Sorry Friend. It's my mistake. Now it's confirmed : The CloneEntity Function is working correctly when I pass the element that I get from the expression :
Dim element = CType(Enumerable.ElementAt(CallByName(MyObj1, "Child1", CallType.Get), k), Child1)
But is not working correctly when I pass the element that I get from this expression :
Dim element = CTypeDynamic(Enumerable.ElementAt(CallByName(MyObj1, "Child1", CallType.Get), k), Type.GetType("MyProg1.Child1,MyProg1,Version=1.0.0, Culture=neutral,PublicKeyToken=null"))
Yes, in the meantime I replicated it - both versions, simplified here:
Dim el = Enumerable.ElementAt(CallByName(MyClass, "Children", CallType.Get), 1)
REM 1
Dim el1 = CType(el, ChildClass)
Dim el1copy = CopyEntity(el1) REM works. (el1copy is of type ChildClass)REM 2
Dim el2 = CTypeDynamic(Of ChildClass)(el)
Dim el2copy = CopyEntity(el2) REM works. (el2copy is of type ChildClass)REM 3
Dim el3 = CTypeDynamic(el, GetType(ChildClass))
Dim el3copy = CopyEntity(el3) REM doesn't work. (el3copy is of type Object)That's basically the same as your code above. And it's still the same as what I'm talking about for the last messages ;P I know you can't use 1 and 2. The reason they work is because the return type of CType(el, ChildClass) and CTypeDynamic(Of ChildClass)(el) is ChildClass. The reason 3 doesn't work is because the return type of CTypeDynamic(el, GetType(ChildClass)) is Object (so it doesn't have anything to do with Type.GetType(..)). So, for 1 and 2 CopyEntity(..) is called for the correct generic type, for 3 it's called with Object as generic type. I don't know if there's a way to make 3 work. I tested the same thing (as 3) in C# and it actually works. Either VB differs there from C# or I just don't know how to do it in VB. I can assure you though that the reflection-approach that I suggested would work. If you want to find out if there is a way to make 3 work I would suggest you post a new question so that someone who knows VB better than me will be more likely to notice.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
Yes, in the meantime I replicated it - both versions, simplified here:
Dim el = Enumerable.ElementAt(CallByName(MyClass, "Children", CallType.Get), 1)
REM 1
Dim el1 = CType(el, ChildClass)
Dim el1copy = CopyEntity(el1) REM works. (el1copy is of type ChildClass)REM 2
Dim el2 = CTypeDynamic(Of ChildClass)(el)
Dim el2copy = CopyEntity(el2) REM works. (el2copy is of type ChildClass)REM 3
Dim el3 = CTypeDynamic(el, GetType(ChildClass))
Dim el3copy = CopyEntity(el3) REM doesn't work. (el3copy is of type Object)That's basically the same as your code above. And it's still the same as what I'm talking about for the last messages ;P I know you can't use 1 and 2. The reason they work is because the return type of CType(el, ChildClass) and CTypeDynamic(Of ChildClass)(el) is ChildClass. The reason 3 doesn't work is because the return type of CTypeDynamic(el, GetType(ChildClass)) is Object (so it doesn't have anything to do with Type.GetType(..)). So, for 1 and 2 CopyEntity(..) is called for the correct generic type, for 3 it's called with Object as generic type. I don't know if there's a way to make 3 work. I tested the same thing (as 3) in C# and it actually works. Either VB differs there from C# or I just don't know how to do it in VB. I can assure you though that the reflection-approach that I suggested would work. If you want to find out if there is a way to make 3 work I would suggest you post a new question so that someone who knows VB better than me will be more likely to notice.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
Thank you ! Please , can you post here the code ( of variant 3 ) that works on C# ? ( I mean the whole code that you have tested , with the Copyentity function too ). Thank you !
Sure, here you go:
class ChildClass
{ }class MyClass
{
public ICollection<ChildClass> Children { get; set; }public MyClass() { Children = new HashSet<ChildClass>() { new ChildClass() }; }
}
T CopyEntity(T entity)
where T : class, new()
{
T copy = new T();
// actual copying omitted here
// for testing only the return type matters
return copy;
}void Test()
{
MyClass myClass = new MyClass();
dynamic children = typeof(MyClass).GetProperty("Children").GetValue(myClass);
dynamic child = Enumerable.ElementAt(children, 0);
dynamic copy = CopyEntity(child);
// copy is of type ChildClass
}If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
Sure, here you go:
class ChildClass
{ }class MyClass
{
public ICollection<ChildClass> Children { get; set; }public MyClass() { Children = new HashSet<ChildClass>() { new ChildClass() }; }
}
T CopyEntity(T entity)
where T : class, new()
{
T copy = new T();
// actual copying omitted here
// for testing only the return type matters
return copy;
}void Test()
{
MyClass myClass = new MyClass();
dynamic children = typeof(MyClass).GetProperty("Children").GetValue(myClass);
dynamic child = Enumerable.ElementAt(children, 0);
dynamic copy = CopyEntity(child);
// copy is of type ChildClass
}If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Thank you ! But your code in C# when is converted in vb.net ( with code converters ) , is :
Class ChildClass
End ClassClass [MyClass]
Public Property Children() As ICollection(Of ChildClass)
Get
Return m_Children
End Get
Set
m_Children = Value
End Set
End Property
Private m_Children As ICollection(Of ChildClass)Public Sub New() Children = New HashSet(Of ChildClass)() From { \_ New ChildClass() \_ } End Sub
End Class
Private Function CopyEntity(Of T As {Class, New})(entity As T) As T
Dim copy As New T()
' actual copying omitted here
' for testing only the return type matters
Return copy
End FunctionPrivate Sub Test()
Dim [myClass] As New [MyClass]()
Dim children As dynamic = GetType([MyClass]).GetProperty("Children").GetValue([myClass])
Dim child As dynamic = Enumerable.ElementAt(children, 0)
Dim copy As dynamic = CopyEntity(child)
' copy is of type ChildClass
End Suband this code is not using CTypeDynamic. So what you have tested in vb.net that doesn't work ? and on my vb.net code , the error came up on the line :
Dim en = ctx.Entry(clone)
and you don't have a such line in your code. ............................. Also I try to implement your version with reflection , but I can't make it work on vb.net ? can you provide some more help ? .............................. Thank you !
-
Thank you ! But your code in C# when is converted in vb.net ( with code converters ) , is :
Class ChildClass
End ClassClass [MyClass]
Public Property Children() As ICollection(Of ChildClass)
Get
Return m_Children
End Get
Set
m_Children = Value
End Set
End Property
Private m_Children As ICollection(Of ChildClass)Public Sub New() Children = New HashSet(Of ChildClass)() From { \_ New ChildClass() \_ } End Sub
End Class
Private Function CopyEntity(Of T As {Class, New})(entity As T) As T
Dim copy As New T()
' actual copying omitted here
' for testing only the return type matters
Return copy
End FunctionPrivate Sub Test()
Dim [myClass] As New [MyClass]()
Dim children As dynamic = GetType([MyClass]).GetProperty("Children").GetValue([myClass])
Dim child As dynamic = Enumerable.ElementAt(children, 0)
Dim copy As dynamic = CopyEntity(child)
' copy is of type ChildClass
End Suband this code is not using CTypeDynamic. So what you have tested in vb.net that doesn't work ? and on my vb.net code , the error came up on the line :
Dim en = ctx.Entry(clone)
and you don't have a such line in your code. ............................. Also I try to implement your version with reflection , but I can't make it work on vb.net ? can you provide some more help ? .............................. Thank you !
dilkonika wrote:
and this code is not using CTypeDynamic.
Because it works without it. For completeness, I included the analog into the VB-version:
Public Class ChildClass End Class Public Class SomeClass Public Property Children As ICollection(Of ChildClass) = New HashSet(Of ChildClass) End Class Public Function CopyEntity(Of T As {Class, New})(entity As T) As T Dim clone As New T() Return clone End Function Sub Main() Dim someClass = New SomeClass someClass.Children.Add(New ChildClass) Dim el = Enumerable.ElementAt(CallByName(someClass, "Children", CallType.Get), 0) Dim elcopy = CopyEntity(el) REM without CTypeDynamic. doesn't work. (elcopy is Object) Dim el1 = CType(el, ChildClass) Dim el1copy = CopyEntity(el1) REM works (el1copy is ChildClass) Dim el2 = CTypeDynamic(Of ChildClass)(el) Dim el2copy = CopyEntity(el2) REM works (el2copy is ChildClass) Dim el3 = CTypeDynamic(el, GetType(ChildClass)) Dim el3copy = CopyEntity(el3) REM doesn't work (el3copy is Object) End Sub
Quote:
and on my vb.net code , the error came up on the line : Dim en = ctx.Entry(clone) and you don't have a such line in your code.
Because the reason why it not works (when it not works) is because clone is of type Object and not of type ChildClass. So I only have to check for the type of clone to know if your line ctx.Entry(clone) would work.
dilkonika wrote:
Also I try to implement your version with reflection , but I can't make it work on vb.net ? can you provide some more help ?
Please post what you have so far.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
dilkonika wrote:
and this code is not using CTypeDynamic.
Because it works without it. For completeness, I included the analog into the VB-version:
Public Class ChildClass End Class Public Class SomeClass Public Property Children As ICollection(Of ChildClass) = New HashSet(Of ChildClass) End Class Public Function CopyEntity(Of T As {Class, New})(entity As T) As T Dim clone As New T() Return clone End Function Sub Main() Dim someClass = New SomeClass someClass.Children.Add(New ChildClass) Dim el = Enumerable.ElementAt(CallByName(someClass, "Children", CallType.Get), 0) Dim elcopy = CopyEntity(el) REM without CTypeDynamic. doesn't work. (elcopy is Object) Dim el1 = CType(el, ChildClass) Dim el1copy = CopyEntity(el1) REM works (el1copy is ChildClass) Dim el2 = CTypeDynamic(Of ChildClass)(el) Dim el2copy = CopyEntity(el2) REM works (el2copy is ChildClass) Dim el3 = CTypeDynamic(el, GetType(ChildClass)) Dim el3copy = CopyEntity(el3) REM doesn't work (el3copy is Object) End Sub
Quote:
and on my vb.net code , the error came up on the line : Dim en = ctx.Entry(clone) and you don't have a such line in your code.
Because the reason why it not works (when it not works) is because clone is of type Object and not of type ChildClass. So I only have to check for the type of clone to know if your line ctx.Entry(clone) would work.
dilkonika wrote:
Also I try to implement your version with reflection , but I can't make it work on vb.net ? can you provide some more help ?
Please post what you have so far.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Thank you ! But for the Reflection version , I just converted the code to vb.net but I don't know how to integreate with my code. If you can just post your full version for C# with reflection so I can understand more ( I don't have so much knowledge about reflection , but at this point I really need a solution for my problem , so I need to use it )
-
Thank you ! But for the Reflection version , I just converted the code to vb.net but I don't know how to integreate with my code. If you can just post your full version for C# with reflection so I can understand more ( I don't have so much knowledge about reflection , but at this point I really need a solution for my problem , so I need to use it )
class Program
{
class ChildClass
{ }class SomeClass { public ICollection Children { get; set; } public SomeClass() { Children = new HashSet() { new ChildClass() }; } } public static T CopyEntity(T entity) where T : class, new() { T copy = new T(); return copy; } static void Main(string\[\] args) { SomeClass someClass = new SomeClass(); dynamic children = typeof(SomeClass).GetProperty("Children").GetValue(someClass); object child = Enumerable.ElementAt(children, 0); // if CopyEntity would be not a static method, BindingFlags.Instance // would have to be used, instead of BindingFlags.Static MethodInfo mi = typeof(Program).GetMethod("CopyEntity", BindingFlags.Static | BindingFlags.Public); mi = mi.MakeGenericMethod(new Type\[\] { /\* +typeof(YourContext) \*/ child.GetType() /\* +typeof(bool) \*/ }); // if CopyEntity would be not a static method, the first argument // to Invoke would have to be the class-instance on which to invoke // CopyEntity, instead of null object clone = mi.Invoke(null, new object\[\] { /\* +ctx \*/ child /\* +copyKeys \*/ }); // -> clone is of type ChildClass }
}
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
-
class Program
{
class ChildClass
{ }class SomeClass { public ICollection Children { get; set; } public SomeClass() { Children = new HashSet() { new ChildClass() }; } } public static T CopyEntity(T entity) where T : class, new() { T copy = new T(); return copy; } static void Main(string\[\] args) { SomeClass someClass = new SomeClass(); dynamic children = typeof(SomeClass).GetProperty("Children").GetValue(someClass); object child = Enumerable.ElementAt(children, 0); // if CopyEntity would be not a static method, BindingFlags.Instance // would have to be used, instead of BindingFlags.Static MethodInfo mi = typeof(Program).GetMethod("CopyEntity", BindingFlags.Static | BindingFlags.Public); mi = mi.MakeGenericMethod(new Type\[\] { /\* +typeof(YourContext) \*/ child.GetType() /\* +typeof(bool) \*/ }); // if CopyEntity would be not a static method, the first argument // to Invoke would have to be the class-instance on which to invoke // CopyEntity, instead of null object clone = mi.Invoke(null, new object\[\] { /\* +ctx \*/ child /\* +copyKeys \*/ }); // -> clone is of type ChildClass }
}
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson
Thank you ! Your code is working. Just for curiosity , the other variant is working too. I found this solution in vb.net , to make a change on CopyEntityFunction like this : instead of
Dim clone as New(T)
I use this :
Dim clone = Activator.CreateInstance(entity.GetType())
Now it's working. Thank you for your help.
-
Thank you ! Your code is working. Just for curiosity , the other variant is working too. I found this solution in vb.net , to make a change on CopyEntityFunction like this : instead of
Dim clone as New(T)
I use this :
Dim clone = Activator.CreateInstance(entity.GetType())
Now it's working. Thank you for your help.
dilkonika wrote:
Dim clone = Activator.CreateInstance(entity.GetType())
Yes, that's a simpler solution if you don't need CopyEntity to be generic (that is, if you don't need the static type T for anything else). If you haven't already, you can remove that generic stuff from the declaration of CopyEntity then.
dilkonika wrote:
Thank you for your help.
You're welcome.
If the brain were so simple we could understand it, we would be so simple we couldn't. — Lyall Watson