มีวิธีการสร้างอินสแตนซ์ของคลาสตามข้อเท็จจริงที่ฉันรู้ชื่อของคลาสที่รันไทม์หรือไม่ โดยทั่วไปฉันจะมีชื่อของชั้นในสตริง
มีวิธีการสร้างอินสแตนซ์ของคลาสตามข้อเท็จจริงที่ฉันรู้ชื่อของคลาสที่รันไทม์หรือไม่ โดยทั่วไปฉันจะมีชื่อของชั้นในสตริง
คำตอบ:
ดูที่วิธีการActivator.CreateInstance
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
มันค่อนข้างง่าย สมมติว่า ClassName ของคุณCar
และ namespace จะVehicles
แล้วผ่านพารามิเตอร์ซึ่งผลตอบแทนวัตถุประเภทVehicles.Car
Car
เช่นนี้คุณสามารถสร้างตัวอย่างของคลาสใดก็ได้แบบไดนามิก
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
หากชื่อที่ผ่านการรับรองของคุณ(เช่นVehicles.Car
ในกรณีนี้) อยู่ในการชุมนุมอื่นType.GetType
จะเป็นโมฆะ Type
ในกรณีเช่นนี้คุณมีห่วงผ่านการประกอบและพบว่า เพื่อที่คุณสามารถใช้รหัสด้านล่าง
public object GetInstance(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return Activator.CreateInstance(type);
}
return null;
}
ตอนนี้ถ้าคุณต้องการเรียกตัวสร้างพารามิเตอร์ทำต่อไปนี้
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
แทน
Activator.CreateInstance(t);
dynamic
รหัส - ดูstackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
ด้วยstr
, fullyQualifiedName
จะทำงาน
str
ถูกใช้เป็นส่วนหนึ่งของหลักการตั้งชื่อสำหรับตัวแปร องค์กรและโครงการบางแห่งยืนยันที่จะทำตามสิ่งนี้ดังนั้นฉันจึงใช้ หากคุณจะทำงานใน oraganisation / โครงการคุณจะรู้สิ่งนี้ ตามที่คุณพูดไปโดยไม่มีstr
มันจะทำงาน :) @MehdiDehghani
ฉันใช้วิธีนี้สำเร็จแล้ว:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
คุณจะต้องส่งวัตถุที่ส่งคืนไปยังประเภทวัตถุที่คุณต้องการ
น่าจะเป็นคำถามของฉันควรจะเฉพาะเจาะจงมากขึ้น ฉันรู้คลาสพื้นฐานสำหรับสตริงดังนั้นแก้ไขโดย:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
ชั้น Activator.CreateInstance มีวิธีการต่าง ๆ เพื่อให้ได้สิ่งเดียวกันในวิธีที่ต่างกัน ฉันสามารถโยนมันเป็นวัตถุ แต่สิ่งที่กล่าวมาข้างต้นมีประโยชน์กับสถานการณ์ของฉันมากที่สุด
ฉันรู้ว่าฉันมาช้าไปกับเกม ... แต่วิธีแก้ปัญหาที่คุณกำลังมองหาอาจเป็นการรวมกันของข้างต้นและใช้อินเทอร์เฟซเพื่อกำหนดแง่มุมที่สาธารณชนสามารถเข้าถึงวัตถุของคุณได้
จากนั้นถ้าคลาสทั้งหมดของคุณที่จะสร้างวิธีนี้ใช้อินเทอร์เฟซนั้นคุณก็สามารถส่งเป็นประเภทอินเตอร์เฟสและทำงานกับวัตถุผลลัพธ์
ในการสร้างอินสแตนซ์ของคลาสจากโครงการอื่นในโซลูชันคุณสามารถขอรับแอสเซมบลีที่ระบุโดยชื่อของคลาสใด ๆ (เช่น BaseEntity) และสร้างอินสแตนซ์ใหม่:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
ตัวอย่างเช่นหากคุณเก็บค่าประเภทต่าง ๆ ในฟิลด์ฐานข้อมูล (เก็บไว้เป็นสตริง) และมีฟิลด์อื่นที่มีชื่อประเภท (เช่น String, bool, int, MyClass) จากนั้นจากข้อมูลของเขตข้อมูลนั้นคุณสามารถทำได้ สร้างคลาสประเภทใดก็ได้โดยใช้โค้ดด้านบนและเติมด้วยค่าจากฟิลด์แรก แน่นอนนี้ขึ้นอยู่กับประเภทที่คุณกำลังเก็บมีวิธีการแยกสตริงเป็นประเภทที่ถูกต้อง ฉันใช้หลายครั้งในการจัดเก็บการตั้งค่าผู้ใช้ในฐานข้อมูล
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
ทำไมคุณถึงต้องการเขียนรหัสเช่นนี้? หากคุณมีคลาส 'ReportClass' คุณสามารถสร้างอินสแตนซ์ของมันได้โดยตรงตามที่แสดงด้านล่าง
ReportClass report = new ReportClass();
รหัสReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
จะถูกใช้เมื่อคุณไม่มีคลาสที่จำเป็น แต่คุณต้องการสร้างอินสแตนซ์และหรือหรือเรียกใช้เมธอดแบบไดนามิก
ฉันหมายความว่ามันจะเป็นประโยชน์เมื่อ u รู้การชุมนุม แต่ในขณะที่เขียนรหัสที่คุณไม่ได้มีชั้นเรียนReportClass
ที่มีอยู่