C# 从字符串名称实例化一个 Class
C# Instantiate a Class from String name
有多个 classes 做很多事情,我不得不实例化其中之一,填充一些属性并调用一个方法。示例将具有以下方法,例如
public class Method100Response201
{
public string R1_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something Blue..}"); }
}
public class Method100Response404
{
public string R2_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something Old..}"); }
}
public class Method110Response200
{
public string R3_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something New..}"); }
}
所有这些都在程序 class 中的同一个命名空间中,我有机制找出我需要哪个 Class:
static void Main(string[] args)
{
int[] MethodResponse = DoSomethingHere (23, "something", true);
string DerivedClassName = ResponseModel(MethodResponse[0], MethodResponse[1]);
Console.WriteLine (
"For method " + MethodResponse[0].ToString ()
+ " and response " + MethodResponse[1].ToString ()
+ " you must instantiate Class "
+ DerivedClassName);
Console.ReadKey ();
//how do I do this????
//const string objectToInstantiate = "MyProject.Domain.MyNewTestClass, MyTestProject";
//var objectType = Type.GetType (objectToInstantiate);
//dynamic instantiatedObject = Activator.CreateInstance (objectType) as ITestClass;
// set a property value
//instantiatedObject.Name = DerivedClassName;
// get a property value
//string name = instantiatedObject.Name;
// call a method - output "Something Blue.."
//Console.Write (instantiatedObject.DoSpecialThing ());
}
public static int[] DoSomethingHere (int param1, string param2, bool whatever)
{
int firstInt = 0; int secondInt = 0;
//
//lots of work here, I end up with method and selector..
//
firstInt = 100;
secondInt = 201;
return new int[] { firstInt, secondInt };
}
public static string ResponseModel(int method, int response)
{
string returnClass = String.Empty;
switch (method)
{
case 100:
if (response == 201)
{ Console.WriteLine ("Case 100,201"); returnClass = "Method100Response201"; }
else
{ Console.WriteLine ("Case 100,404"); returnClass = "Method100Response404"; }
break;
case 110:
Console.WriteLine ("Case 100,404"); returnClass = "Method110Response200";
break;
case 120:
// ...
break;
}
return returnClass;
}
我尝试过一种叫做 Activator 的东西,我不是专家,这对我来说真的很重要。有人可以帮我吗? (基于 SO 中已发布的解决方案,我对我正在尝试的一些代码发表了评论。谢谢)。
这个技术叫做Reflection,意思是从字符串中调用一个实例。
我的电话 class 将是
public class Class1
{
public string Property { get; set; } = "I'm class1";
public void DoSpecialThings()
{
Console.WriteLine("Class1 does special things");
}
}
接下来我在静态函数中创建一个实例,应该将所有 classes 放在同一个命名空间中以便于控制
public static dynamic GetClassFromString(string className)
{
var classAddress = $"NetCoreScripts.{className}";
Type type = GetType(classAddress);
// Check whether the class is existed?
if (type == null)
return null;
// Then create an instance
object instance = Activator.CreateInstance(type);
return instance;
}
还有一个 GetType 方法
public static Type GetType(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return type;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return type;
}
return null;
}
我用动态类型实现很快,基本上你可以用接口显式编码。
static async Task Main(string[] args)
{
dynamic instance = GetClassFromString("Class1");
Console.WriteLine(instance.GetType().FullName); //NetCoreScripts.Class1
Console.WriteLine(instance.GetType().Name); //Class1
Console.WriteLine(instance.Property); //I'm class1
instance.Property = "Class1 has been changed";
Console.WriteLine(instance.Property); //Class1 has been changed
instance.DoSpecialThings(); // Class1 does special things
}
您要解决的问题与创建新对象有关。 Here 是一些常用的编码模式。
我想说这是工厂模式的一个很好的用例。我们所做的是将创建对象的责任委托给 factory.
首先,我们可以将它们识别为扩展抽象 class
的 classes
public abstract class MehodResponseBase {
public abstract void DoSpecialThing();
public abstract string responseText;
}
public class Method100Response201 : MehodResponseBase
{
public override responseText = "Method100Response201";
public string R1_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something Blue..}"); }
}
public class Method100Response404 : MehodResponseBase
{
public override responseText = "Method100Response404";
public string R2_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something Old..}"); }
}
public class Method110Response200 : MehodResponseBase
{
public override responseText = "Method110Response200";
public string R3_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something New..}"); }
}
然后我们可以将他们的创建提取到工厂中
pubic class MethodResponseFactory()
{
public static MehodResponseBase Make(int method, int response)
{
if (method == 100)
{
if(response == 201)
{
return new Method100Response201();
}
if(response == 404)
{
return new Method100Response404();
}
}
if (method == 110)
{
if (response == 200)
{
return new Method110Response200();
}
}
throw new MethodResponseCreationException($"Cannot create for mothod: {method} and response: {response}")
}
}
因此您的响应模型被重构为
public static string ResponseModel(int method, int response)
{
try
{
return MethodResponseFactory.Make(method, response).returnClass;
}
catch (MethodResponseCreationException ex)
{
return string.Empty;
}
}
因此,如您所见,创建对象的所有委托现在都在工厂中。而 resonseModel
class 只是调用工厂在 method
和 response
.
的基础上构建一个 class
有多个 classes 做很多事情,我不得不实例化其中之一,填充一些属性并调用一个方法。示例将具有以下方法,例如
public class Method100Response201
{
public string R1_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something Blue..}"); }
}
public class Method100Response404
{
public string R2_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something Old..}"); }
}
public class Method110Response200
{
public string R3_01 { get; set; }
public void DoSpecialThing()
{ Console.WriteLine ("Something New..}"); }
}
所有这些都在程序 class 中的同一个命名空间中,我有机制找出我需要哪个 Class:
static void Main(string[] args)
{
int[] MethodResponse = DoSomethingHere (23, "something", true);
string DerivedClassName = ResponseModel(MethodResponse[0], MethodResponse[1]);
Console.WriteLine (
"For method " + MethodResponse[0].ToString ()
+ " and response " + MethodResponse[1].ToString ()
+ " you must instantiate Class "
+ DerivedClassName);
Console.ReadKey ();
//how do I do this????
//const string objectToInstantiate = "MyProject.Domain.MyNewTestClass, MyTestProject";
//var objectType = Type.GetType (objectToInstantiate);
//dynamic instantiatedObject = Activator.CreateInstance (objectType) as ITestClass;
// set a property value
//instantiatedObject.Name = DerivedClassName;
// get a property value
//string name = instantiatedObject.Name;
// call a method - output "Something Blue.."
//Console.Write (instantiatedObject.DoSpecialThing ());
}
public static int[] DoSomethingHere (int param1, string param2, bool whatever)
{
int firstInt = 0; int secondInt = 0;
//
//lots of work here, I end up with method and selector..
//
firstInt = 100;
secondInt = 201;
return new int[] { firstInt, secondInt };
}
public static string ResponseModel(int method, int response)
{
string returnClass = String.Empty;
switch (method)
{
case 100:
if (response == 201)
{ Console.WriteLine ("Case 100,201"); returnClass = "Method100Response201"; }
else
{ Console.WriteLine ("Case 100,404"); returnClass = "Method100Response404"; }
break;
case 110:
Console.WriteLine ("Case 100,404"); returnClass = "Method110Response200";
break;
case 120:
// ...
break;
}
return returnClass;
}
我尝试过一种叫做 Activator 的东西,我不是专家,这对我来说真的很重要。有人可以帮我吗? (基于 SO 中已发布的解决方案,我对我正在尝试的一些代码发表了评论。谢谢)。
这个技术叫做Reflection,意思是从字符串中调用一个实例。 我的电话 class 将是
public class Class1
{
public string Property { get; set; } = "I'm class1";
public void DoSpecialThings()
{
Console.WriteLine("Class1 does special things");
}
}
接下来我在静态函数中创建一个实例,应该将所有 classes 放在同一个命名空间中以便于控制
public static dynamic GetClassFromString(string className)
{
var classAddress = $"NetCoreScripts.{className}";
Type type = GetType(classAddress);
// Check whether the class is existed?
if (type == null)
return null;
// Then create an instance
object instance = Activator.CreateInstance(type);
return instance;
}
还有一个 GetType 方法
public static Type GetType(string strFullyQualifiedName)
{
Type type = Type.GetType(strFullyQualifiedName);
if (type != null)
return type;
foreach (var asm in AppDomain.CurrentDomain.GetAssemblies())
{
type = asm.GetType(strFullyQualifiedName);
if (type != null)
return type;
}
return null;
}
我用动态类型实现很快,基本上你可以用接口显式编码。
static async Task Main(string[] args)
{
dynamic instance = GetClassFromString("Class1");
Console.WriteLine(instance.GetType().FullName); //NetCoreScripts.Class1
Console.WriteLine(instance.GetType().Name); //Class1
Console.WriteLine(instance.Property); //I'm class1
instance.Property = "Class1 has been changed";
Console.WriteLine(instance.Property); //Class1 has been changed
instance.DoSpecialThings(); // Class1 does special things
}
您要解决的问题与创建新对象有关。 Here 是一些常用的编码模式。
我想说这是工厂模式的一个很好的用例。我们所做的是将创建对象的责任委托给 factory.
首先,我们可以将它们识别为扩展抽象 class
的 classespublic abstract class MehodResponseBase {
public abstract void DoSpecialThing();
public abstract string responseText;
}
public class Method100Response201 : MehodResponseBase
{
public override responseText = "Method100Response201";
public string R1_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something Blue..}"); }
}
public class Method100Response404 : MehodResponseBase
{
public override responseText = "Method100Response404";
public string R2_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something Old..}"); }
}
public class Method110Response200 : MehodResponseBase
{
public override responseText = "Method110Response200";
public string R3_01 { get; set; }
public override void DoSpecialThing()
{ Console.WriteLine ("Something New..}"); }
}
然后我们可以将他们的创建提取到工厂中
pubic class MethodResponseFactory()
{
public static MehodResponseBase Make(int method, int response)
{
if (method == 100)
{
if(response == 201)
{
return new Method100Response201();
}
if(response == 404)
{
return new Method100Response404();
}
}
if (method == 110)
{
if (response == 200)
{
return new Method110Response200();
}
}
throw new MethodResponseCreationException($"Cannot create for mothod: {method} and response: {response}")
}
}
因此您的响应模型被重构为
public static string ResponseModel(int method, int response)
{
try
{
return MethodResponseFactory.Make(method, response).returnClass;
}
catch (MethodResponseCreationException ex)
{
return string.Empty;
}
}
因此,如您所见,创建对象的所有委托现在都在工厂中。而 resonseModel
class 只是调用工厂在 method
和 response
.