|
Using MakeGenericType and Activator.CreateInstance() to make a generic Type at runtime returns an Object: to make a usable instance of that Object, you have to cast it to its "native" Type.
surprise: i stumbled across a way to get a usable instance of the Object ... without explicit casting ... by using 'dynamic'; example:
Type generic = typeof(Dictionary<,>);
Type[] typeArgs = { typeof(string), typeof(string) };
Type newGenericType = generic.MakeGenericType(typeArgs);
dynamic instance = Activator.CreateInstance(newGenericType);
instance.Add("1", "2"); I am not sure, how, in this case, use of 'dynamic' works.
Appreciate your thoughts.
Note: afaik, no example of this technique occurs in any MS documentation.
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
dynamic uses late-binding. Behind the scenes, it will use reflection to find and invoke the appropriate Add method on the run-time type of the object, with a suitable sprinkling of call-site caching to improve performance.
Simon Cooper published a series of blog posts on that topic back in 2012:
Inside the DLR - Callsites - Simple Talk[^]
Inside the DLR - Callsite binders - Simple Talk[^]
Inside the DLR - Invoking methods - Simple Talk[^]
NB: For the generic collections, you can probably avoid the DLR overhead by using the non-generic interfaces instead:
Type unboundType = typeof(Dictionary<,>);
Type[] typeArgs = { typeof(string), typeof(string) };
Type constructedType = generic.MakeGenericType(typeArgs);
IDictionary instance = (IDictionary)Activator.CreateInstance(constructedType);
instance.Add("1", "2");
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
Thank you ! Your example of using the unbound Type is very interesting.
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
Dynamic types skip all compile time checking in favour of runtime checking - that includes method names, return types, number of parameters, type of parameters, or even that the method exists at all.
So because the return value is declared as dynamic , the compiler doesn't care what you try to call - and at run time the checks are done and the right method is called.
Try it:
dynamic items = new List<string>();
items.Add("Hello");
items.Add("World");
Console.WriteLine(string.Join(" ", items));
items.FallOverAndDie();
Will give you:
Hello World
Unhandled exception. Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: 'System.Collections.Generic.List<string>' does not contain a definition for 'FallOverAndDie'
at CallSite.Target(Closure , CallSite , Object )
at System.Dynamic.UpdateDelegates.UpdateAndExecuteVoid1[T0](CallSite site, T0 arg0)
at Program.Main(String[] args) Because the collection does not contain a FallOverAndDie method.
dynamic items = new List<string>();
items.Add("Hello");
items.Add("World");
Console.WriteLine(string.Join(" ", items));
items = new Dictionary<int, int>();
items.Add("Hello");
items.Add("World");
Console.WriteLine(string.Join(" ", items));
Will fail because the Dictionary class has no overload with just one parameter.
Personally, I'm still not convinced that adding dynamic to the language was a good idea - it seems too much like a way to move compile time errors to runtime and break strong typing ...
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thanks !OriginalGriff wrote: Dynamic types skip all compile time checking in favour of runtime checking I was aware of that, but, still felt there was some "spooky action at a distance" going on when it came to this specific type of Type creation.
i find the two examples that "fail" rather strange in this context because they contain rather obvious programming errors ... i think your point is the lack of compile checking, which is generally known by anyone who uses 'dynamic.OriginalGriff wrote: Personally, I'm still not convinced that adding dynamic to the language was a good idea - it seems too much like a way to move compile time errors to runtime and break strong typing ... imho, that's a very interesting topic for debating what a supposedly strongly-typed language should expose for use by programmers.
Should it expose reflection, and dynamic, facilities ? Allow use of facilities that allow access to OS internals the way C# lets you use API's ? Expose Activator ? Expose a REPL facility ? i suppose an "extremist" might even oppose facilities like generics, and Linq, and extension methods.
i see use of 'dynamic as "dangerous," but useful when you absolutely have to have a "bag" of mixed Types and use of casting to interface is unwanted ... a whole lot better implementation than the now deprecated 'ArrayList.
The run-time creation and instantiation of generic Types seems valuable to me for creating object factories.
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
I can see the intention, but I think that (just like var ) it's too open to abuse.
With dynamic you can "get rid of all compiler errors" and provided your tests never reach the "bad code" you won't know until it fails in production. Which is against the whole ethos of C# and strong typing ...
It's a personal thing: I don't like production errors that I can catch as early as possible in the development process.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I hear what you say, and I think using Dynamic is similar to surgery ... you want it performed only when necessary, and, you want a specialist using the knife, not your pharmacist
If I want a "bag" of objects of various Types ... the number of them, and their Types, known only at run-time ... Dynamic and ExpandoObject are usable ... without the gut-busting required to use something like Reflection/CodeDom/Emit.
The creation of generic "factory classes" that create specific instances of Classes at run-time is, imho, a kind of special case.
imho, later versions of C# added generics, Extension methods, Dynamic, Linq, use of var, etc., because there was a compelling demand for them.
cheers, Bill
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
can u add some more transition effect like up down mix, left right mix, horizontal expand?
i am looking for support for add some drawing tool same inside like pen, circle with colour pattle selection in matrix area.
i am unable to wrote code . so need help.
|
|
|
|
|
Don't post this here - if you got the code from an article, then there is a "Add a Comment or Question" button at the bottom of that article, which causes an email to be sent to the author. They are then alerted that you wish to speak to them.
Posting this here relies on them "dropping by" and realising it is for them.
"I have no idea what I did, but I'm taking full credit for it." - ThisOldTony
"Common sense is so rare these days, it should be classified as a super power" - Random T-shirt
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
I have my own custom list class in my utility library (provide some additional benefits like having buildin readonly view or being observable or being undoable)
and I am just migrating to .NET5 and pondering the nullable reference implication.
my type is like so:
public class DocumentList<T> : IList<T>, IList
{
}
but what of that method
object? System.Collections.IList.this[int index]
{
get { return this[index]; }
set { this[index] = (T)value; }
}
value could be null, so .. perhaps I should throw an exception if value is null?
But what if one make a DocumentList<T?> then I expect the values to be null and should not throw an exception...
EDIT2 In fact.. that MSDN snippet below.. doesn't properly test that! :/
EDIT answering my own question, thanks to MSDN reference source Reference Source
internal static void IfNullAndNullsAreIllegalThenThrow<T>(object value, ExceptionArgument argName)
{
if (value == null && !(default(T) == null))
ThrowHelper.ThrowArgumentNullException(argName);
}
modified 25-Sep-21 12:45pm.
|
|
|
|
|
Hi,
I tried to convert time representation (for example from 8:22PM to 20:22:00). Itried this code in LinqPad and it worked but in VS it doen not work well.
<pre>public static string TimeConverter(string time)
{
string formattedTime;
string[] tSeperate = time.Split(':');
string hour = tSeperate[0];
string minut = string.Empty;
List<char> number = tSeperate[1].Where(x => char.IsNumber(x)).Select(x => x).ToList();
int n = number.Count();
for (int i = 0; i < n; i++)
{
if (i + 1 < n)
{
minut = string.Format(@"{0}{1}", number[i], number[i + 1]);
}
}
IEnumerable<char> stringQuery = time.Where(x => char.IsLetter(x)).Select(x => x);
var myChar = stringQuery.First();
if (myChar.ToString() == "P")
{
switch (hour)
{
case "1":
hour = "13";
break;
case "2":
hour = "14";
break;
case "3":
hour = "15";
break;
case "4":
hour = "16";
break;
case "5":
hour = "17";
break;
case "6":
hour = "18";
break;
case "7":
hour = "19";
break;
case "8":
hour = "20";
break;
case "9":
hour = "21";
break;
case "10":
hour = "22";
break;
case "11":
hour = "23";
break;
case "12":
hour = "00";
break;
}
formattedTime = string.Format(@"{0}:{1}:00", hour, minut);
}
else
{
formattedTime = string.Format(@"{0}:{1}:00", hour, minut);
}
return formattedTime;
}
The problem is that the following part cannot detect PM or AM in Visual Studio:
<pre>IEnumerable<char> stringQuery = time.Where(x => char.IsLetter(x)).Select(x => x);
I want to use this code in a for loop to convert the time format of thousands of rows.
Please help me.
|
|
|
|
|
I don't know the details of the date and time classes you're using, but I'd do it (in whatever language) by parsing your 8.22PM into a time variable, then formatting it using a 24hr format.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
That's a lot of code for something the framework already does for you.
public static string TimeConverter(string time)
{
if (!DateTime.TryParseExact(time, "h:mmtt", CultureInfo.InvariantCulture, DateTimeStyles.None, out var value))
{
return string.Empty;
}
return value.ToString("HH:mm:ss", CultureInfo.InvariantCulture);
} DateTime.TryParseExact Method (System) | Microsoft Docs[^]
Custom date and time format strings | Microsoft Docs[^]
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
down-voted
This question, like others you have posted, suggests a pattern where you "throw mud against the wall to see what sticks," and, then, when nothing sticks, you ask other people to sort out your mess.
You need to start doing some research and study before you make code-salad: you should have learned how String.Format works, and what the format options are that specify the desired transformation, from the answers to your previous question.
In the future, in "the real world," if you are ever employed as a programmer, do you think your employer would tolerate your wasting their time ?
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
Others have answered your conversion question but I'm curious as to why you are trying to do this on thousands of rows. Normally, showing AM/PM is a display issue so would be handled when displaying the relevant item. If that's the case, it's generally a bad idea to try and display thousands of items.
|
|
|
|
|
This is a part of the calculation procedure in my project. I need to calculate time differences between two dates (along with times)) and automate the process.
|
|
|
|
|
How is the data stored? Because if it's in DateTime already there is no need to try and convert anything.
|
|
|
|
|
And we come back to the same argument that has been presented to you many times - DON'T STORE YOU DATES AS STRINGS.
Never underestimate the power of human stupidity -
RAH
I'm old. I know stuff - JSOP
|
|
|
|
|
Store the date as a date and your problem goes away altogether. A decision to use strings to represent dates is causing you unnecessary pain here; there's a DateTime datatype for a reason, use that. Think about it, you wouldn't store numbers as strings would you, so why store dates as strings?
|
|
|
|
|
Pete O'Hanlon wrote: you wouldn't store numbers as strings would you?
That may be a very brave assumption.
Software rusts. Simon Stephenson, ca 1994. So does this signature. me, 2012
|
|
|
|
|
Hi,
I want to convert date formatted in yyyy/M/d to yyyy/MM/dd.
Is there any short way to do?
For example: 1400/6/7 to 1400/06/07
|
|
|
|
|
The first thing to clarify is whether you are dealing with a DateTime obtained by use of the Persian Calendar class: System.Globalization.PersianCalendar
... or, are you dealing with a run-time DateTime value on a computer where the OS is using the Persian Calendar as the default ?
Possible resources: Noda Time [^] and [^]
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
I use
System.Globalization.PersianCalendar
|
|
|
|
|
Okay, then is the formatting you want done on a machine using Persian Calendar as the default ?
If yes, then can't standard ToString Format syntax (as used in Farsi ?) give you what you want ?
DateTime dt = new DateTime(1400, 6, 7);
string fmt = dt.ToString("yyyy/MM/dd");
«The mind is not a vessel to be filled but a fire to be kindled» Plutarch
|
|
|
|
|
Thanks, If I use this code to iterate through hundreds of datatable rows, would it consume more memory due to the instantiation?
|
|
|
|
|