क्या कोई Activator.CreateInstance()
उद्देश्य के बारे में विस्तार से बता सकता है?
c#.net
करने का तरीका है Object xyz = Class.forName(className).newInstance();
।
क्या कोई Activator.CreateInstance()
उद्देश्य के बारे में विस्तार से बता सकता है?
c#.net
करने का तरीका है Object xyz = Class.forName(className).newInstance();
।
जवाबों:
कहो कि आपके पास MyFancyObject
नीचे इस तरह एक वर्ग है :
class MyFancyObject
{
public int A { get;set;}
}
यह आपको मुड़ने देता है:
String ClassName = "MyFancyObject";
में
MyFancyObject obj;
का उपयोग करते हुए
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
और फिर सामान की तरह कर सकते हैं:
obj.A = 100;
यही इसका उद्देश्य है। इसमें कई अन्य अधिभार भी हैं जैसे कि Type
एक स्ट्रिंग में वर्ग नाम के बजाय प्रदान करना । क्यों आपको एक समस्या होगी जैसे कि एक अलग कहानी है। यहाँ कुछ लोग हैं जिन्हें इसकी आवश्यकता है:
String ClassName = "My.Namespace.MyFancyObject";
) में नामस्थान को शामिल करूं ।
obj = (MyFancyObject)Activator.CreateInstance("MyAssembly", ClassName))
लेकिन टाइप के साथ कास्टिंग करने के बजाय। ClassName से बने प्रकार के साथ कास्ट करें? इस तरह Type type = Type.GetType(ClassName);obj = (type )Activator.CreateInstance("MyAssembly", ClassName))
?
वैसे मैं आपको एक उदाहरण दे सकता हूं कि ऐसा कुछ क्यों इस्तेमाल किया जाए। एक गेम के बारे में सोचें जहां आप अपने स्तर और दुश्मनों को एक्सएमएल फाइल में स्टोर करना चाहते हैं। जब आप इस फ़ाइल को पार्स करते हैं, तो आपके पास इस तरह का एक तत्व हो सकता है।
<Enemy X="10" Y="100" Type="MyGame.OrcGuard"/>
अब आप क्या कर सकते हैं, गतिशील रूप से अपने स्तर की फ़ाइल में मिली वस्तुओं को बनाएं।
foreach(XmlNode node in doc)
var enemy = Activator.CreateInstance(null, node.Attributes["Type"]);
गतिशील एनवायरमेंट बनाने के लिए यह बहुत उपयोगी है। बेशक, इसका उपयोग प्लगिन या एडिन परिदृश्यों के लिए भी करना संभव है और बहुत अधिक।
मेरा अच्छा दोस्त MSDN इसे आपको एक उदाहरण के साथ समझा सकता है
भविष्य में लिंक या सामग्री परिवर्तन के मामले में यहाँ कोड है:
using System;
class DynamicInstanceList
{
private static string instanceSpec = "System.EventArgs;System.Random;" +
"System.Exception;System.Object;System.Version";
public static void Main()
{
string[] instances = instanceSpec.Split(';');
Array instlist = Array.CreateInstance(typeof(object), instances.Length);
object item;
for (int i = 0; i < instances.Length; i++)
{
// create the object from the specification string
Console.WriteLine("Creating instance of: {0}", instances[i]);
item = Activator.CreateInstance(Type.GetType(instances[i]));
instlist.SetValue(item, i);
}
Console.WriteLine("\nObjects and their default values:\n");
foreach (object o in instlist)
{
Console.WriteLine("Type: {0}\nValue: {1}\nHashCode: {2}\n",
o.GetType().FullName, o.ToString(), o.GetHashCode());
}
}
}
// This program will display output similar to the following:
//
// Creating instance of: System.EventArgs
// Creating instance of: System.Random
// Creating instance of: System.Exception
// Creating instance of: System.Object
// Creating instance of: System.Version
//
// Objects and their default values:
//
// Type: System.EventArgs
// Value: System.EventArgs
// HashCode: 46104728
//
// Type: System.Random
// Value: System.Random
// HashCode: 12289376
//
// Type: System.Exception
// Value: System.Exception: Exception of type 'System.Exception' was thrown.
// HashCode: 55530882
//
// Type: System.Object
// Value: System.Object
// HashCode: 30015890
//
// Type: System.Version
// Value: 0.0
// HashCode: 1048575
आप यह भी कर सकते हैं -
var handle = Activator.CreateInstance("AssemblyName",
"Full name of the class including the namespace and class name");
var obj = handle.Unwrap();
.Unwrap()
यह क्या करता है और यह अन्य समाधानों से कैसे संबंधित है?
CreateInstance
जहाँ यह वापस आता है System.Runtime.Remoting.ObjectHandle
।
एक अच्छा उदाहरण अगले हो सकता है: उदाहरण के लिए आपके पास लकड़हारा का एक सेट है और आप उपयोगकर्ता को कॉन्फ़िगरेशन फ़ाइल के माध्यम से रनटाइम में उपयोग किए जाने वाले प्रकार को निर्दिष्ट करने की अनुमति देते हैं।
फिर:
string rawLoggerType = configurationService.GetLoggerType();
Type loggerType = Type.GetType(rawLoggerType);
ILogger logger = Activator.CreateInstance(loggerType.GetType()) as ILogger;
या एक अन्य मामला यह है कि जब आपके पास एक सामान्य इकाइयां कारखाना होता है, जो इकाई बनाता है, और डीएम से प्राप्त डेटा द्वारा एक इकाई के प्रारंभ पर भी जिम्मेदार होता है:
(स्यूडोकोड)
public TEntity CreateEntityFromDataRow<TEntity>(DataRow row)
where TEntity : IDbEntity, class
{
MethodInfo methodInfo = typeof(T).GetMethod("BuildFromDataRow");
TEntity instance = Activator.CreateInstance(typeof(TEntity)) as TEntity;
return methodInfo.Invoke(instance, new object[] { row } ) as TEntity;
}
typeof(loggerType)
परिणामloggerType is a variable and used like a type
Activator.CreateInstance
विधि एक निर्दिष्ट प्रकार का निर्माण करती है, जिसमें कंस्ट्रक्टर का उपयोग किया जाता है जो निर्दिष्ट मापदंडों से सर्वोत्तम रूप से मेल खाता है।
उदाहरण के लिए, मान लें कि आपके पास स्ट्रिंग के रूप में नाम है, और आप उस प्रकार का उदाहरण बनाने के लिए स्ट्रिंग का उपयोग करना चाहते हैं। आप इसके लिए उपयोग कर सकते हैं Activator.CreateInstance
:
string objTypeName = "Foo";
Foo foo = (Foo)Activator.CreateInstance(Type.GetType(objTypeName));
यहाँ एक MSDN आलेख है जो यह बताता है कि यह अधिक विस्तार से अनुप्रयोग है:
new Foo()
। मुझे लगता है कि ओपी एक अधिक यथार्थवादी उदाहरण चाहता था।
CreateInstance
है कि यदि आप डिजाइन के समय पर ऑब्जेक्ट के प्रकार को नहीं जानते हैं, तो आप तुरंत जा सकते हैं। इस उदाहरण में, आप स्पष्ट रूप से जानते हैं कि यह प्रकार है Foo
क्योंकि आप इसे टाइप कर रहे हैं Foo
। आप ऐसा कभी नहीं करेंगे क्योंकि आप बस कर सकते हैंFoo foo = new Foo()
।
डीप 1 का निर्माण और यह , यहाँ एक स्ट्रिंग में एक वर्ग के नाम को कैसे स्वीकार किया जाए, और फिर इसे LINQ के साथ डेटाबेस में पढ़ने और लिखने के लिए उपयोग करें। मैं डीप 1 की कास्टिंग के बजाय "डायनामिक" का उपयोग करता हूं क्योंकि यह मुझे गुणों को असाइन करने की अनुमति देता है, जो हमें किसी भी टेबल पर गतिशील रूप से चयन करने और संचालित करने की अनुमति देता है जो हम चाहते हैं।
Type tableType = Assembly.GetExecutingAssembly().GetType("NameSpace.TableName");
ITable itable = dbcontext.GetTable(tableType);
//prints contents of the table
foreach (object y in itable) {
string value = (string)y.GetType().GetProperty("ColumnName").GetValue(y, null);
Console.WriteLine(value);
}
//inserting into a table
dynamic tableClass = Activator.CreateInstance(tableType);
//Alternative to using tableType, using Tony's tips
dynamic tableClass = Activator.CreateInstance(null, "NameSpace.TableName").Unwrap();
tableClass.Word = userParameter;
itable.InsertOnSubmit(tableClass);
dbcontext.SubmitChanges();
//sql equivalent
dbcontext.ExecuteCommand("INSERT INTO [TableNme]([ColumnName]) VALUES ({0})", userParameter);
यदि आप पहले से ही वर्ग को जानते हैं और इसे कास्ट करने जा रहे हैं तो आप इसका उपयोग क्यों करेंगे? सिर्फ पुराने तरीके से ही क्यों न करें और कक्षा को हमेशा की तरह बना लें? इस तरह से इसका कोई फायदा नहीं है क्योंकि यह सामान्य रूप से किया जाता है। क्या इस तरह से पाठ लेने और उस पर काम करने का कोई तरीका है:
label1.txt = "Pizza"
Magic(label1.txt) p = new Magic(lablel1.txt)(arg1, arg2, arg3);
p.method1();
p.method2();
अगर मुझे पहले से ही इसका पिज्जा पता है तो इसका कोई फायदा नहीं है:
p = (Pizza)somefancyjunk("Pizza"); over
Pizza p = new Pizza();
लेकिन मुझे लगता है कि अगर यह मौजूद है तो मैजिक पद्धति का एक बड़ा फायदा होगा।
परावर्तन के साथ युग्मित, मुझे Activator.CreateInstance मिला, जो संग्रहीत कार्यविधि को मैप करने में बहुत सहायक होता है, जिसका परिणाम निम्न उत्तर में वर्णित एक कस्टम वर्ग के लिए होता है ।
CreateInstance(Type type)
साथ प्रलेखन से मिलान कियाCreateInstance<T>()
जाए।