Có cách nào để tạo một thể hiện của một lớp dựa trên thực tế tôi biết tên của lớp khi chạy. Về cơ bản tôi sẽ có tên của lớp trong một chuỗi.
Có cách nào để tạo một thể hiện của một lớp dựa trên thực tế tôi biết tên của lớp khi chạy. Về cơ bản tôi sẽ có tên của lớp trong một chuỗi.
Câu trả lời:
Hãy xem phương thức Activator.CreateInstance .
var driver = (OpenQA.Selenium.IWebDriver)Activator.CreateInstance("WebDriver", "OpenQA.Selenium.Firefox.FirefoxDriver").Unwrap();
Nó khá đơn giản. Giả sử rằng tên lớp của bạn là Car
và không gian tên là Vehicles
, sau đó truyền tham số như Vehicles.Car
trả về đối tượng kiểu Car
. Như thế này, bạn có thể tạo bất kỳ trường hợp nào của bất kỳ lớp nào một cách linh hoạt.
public object GetInstance(string strFullyQualifiedName)
{
Type t = Type.GetType(strFullyQualifiedName);
return Activator.CreateInstance(t);
}
Nếu Tên đủ điều kiện của bạn (nghĩa là Vehicles.Car
trong trường hợp này) nằm trong một hội đồng khác, thì Type.GetType
nó sẽ là null. Trong những trường hợp như vậy, bạn có vòng lặp thông qua tất cả các hội đồng và tìm Type
. Cho rằng bạn có thể sử dụng mã dưới đây
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;
}
Bây giờ nếu bạn muốn gọi một hàm tạo tham số, hãy làm như sau
Activator.CreateInstance(t,17); // Incase you are calling a constructor of int type
thay vì
Activator.CreateInstance(t);
dynamic
mã - xem stackoverflow.com/a/2690661/904521 )
strFullyQualifiedName
với str
, fullyQualifiedName
sẽ thực hiện công việc.
str
được sử dụng như một phần của quy ước đặt tên cho các biến. Một số tổ chức và dự án nhất định tuân theo điều này, do đó tôi đã sử dụng. Nếu bạn đã từng làm việc trong một số dự án / dự án nhất định, bạn sẽ biết điều này. Như bạn đã nói mà không str
có nó cũng sẽ thực hiện công việc :) @MehdiDehghani
Tôi đã sử dụng phương pháp này thành công:
System.Reflection.Assembly.GetExecutingAssembly().CreateInstance(string className)
Bạn sẽ cần truyền đối tượng trả về loại đối tượng bạn muốn.
Có lẽ câu hỏi của tôi nên được cụ thể hơn. Tôi thực sự biết một lớp cơ sở cho chuỗi nên đã giải quyết nó bằng cách:
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Lớp Activator.CreateInstance có nhiều phương thức khác nhau để đạt được điều tương tự theo những cách khác nhau. Tôi có thể đã ném nó vào một đối tượng nhưng ở trên có ích nhất cho tình huống của tôi.
Tôi biết tôi đến trễ trò chơi ... nhưng giải pháp bạn đang tìm kiếm có thể là sự kết hợp của những điều trên và sử dụng một giao diện để xác định các đối tượng của bạn có thể truy cập công khai.
Sau đó, nếu tất cả các lớp của bạn sẽ được tạo theo cách này thực hiện giao diện đó, bạn có thể chỉ cần chọn làm loại giao diện và làm việc với đối tượng kết quả.
Để tạo một thể hiện của một lớp từ một dự án khác trong giải pháp, bạn có thể lấy cụm được chỉ định bằng tên của bất kỳ lớp nào (ví dụ BaseEntity) và tạo một thể hiện mới:
var newClass = System.Reflection.Assembly.GetAssembly(typeof(BaseEntity)).CreateInstance("MyProject.Entities.User");
Ví dụ: nếu bạn lưu trữ các giá trị của các loại khác nhau trong trường cơ sở dữ liệu (được lưu dưới dạng chuỗi) và có một trường khác có tên loại (ví dụ: Chuỗi, bool, int, MyClass), thì từ dữ liệu trường đó, bạn có thể, có thể hiểu được, tạo một lớp của bất kỳ loại nào bằng cách sử dụng đoạn mã trên và điền vào nó với giá trị từ trường đầu tiên. Điều này tất nhiên phụ thuộc vào loại bạn đang lưu trữ có một phương pháp để phân tích các chuỗi thành đúng loại. Tôi đã sử dụng điều này nhiều lần để lưu trữ cài đặt tùy chọn người dùng trong cơ sở dữ liệu.
ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
Tại sao bạn muốn viết một mã như thế này? Nếu bạn có sẵn một lớp 'Báo cáo', bạn có thể khởi tạo nó trực tiếp như hiển thị bên dưới.
ReportClass report = new ReportClass();
Mã ReportClass report = (ReportClass)Activator.CreateInstance(Type.GetType(reportClass));
được sử dụng khi bạn không có sẵn lớp cần thiết, nhưng bạn muốn khởi tạo và hoặc gọi một phương thức một cách linh hoạt.
Tôi có nghĩa là nó hữu ích khi bạn biết lắp ráp nhưng trong khi viết mã, bạn không có lớp ReportClass
có sẵn.