我有一个通用方法,声明如下:
public void Duplicate<EntityType>() { ... }
因此,通常使用它只需要这样做:
myObject.Duplicate<int>()
但是,这里我想通过一个变量传递类型,但是它不起作用,以下是我的尝试方法:
Type myType = anObject.GetType();
myObject.Duplicate<myType>();
有人能帮我吗?
提前感谢。
我有一个通用方法,声明如下:
public void Duplicate<EntityType>() { ... }
myObject.Duplicate<int>()
但是,这里我想通过一个变量传递类型,但是它不起作用,以下是我的尝试方法:
Type myType = anObject.GetType();
myObject.Duplicate<myType>();
有人能帮我吗?
提前感谢。
你必须使用反射,基本上是这样的:
MethodInfo method = typeof(...).GetMethod("Duplicate");
MethodInfo generic = method.MakeGenericMethod(myType);
generic.Invoke(myObject, null);
如果您将类型设置为变量,则很难为通用方法找到一个好的候选项,特别是当您的方法不返回任何内容时。
使用以下代码会更好:
public void Duplicate(Type entityType) { ... }
Type myType = anObject.GetType();
myObject.Duplicate(myType);
void
),也没有输入参数。基本上唯一的输入是类型参数。这意味着在您的通用方法内部,您可能正在执行像以下内容的操作:public void Duplicate<EntityType>()
{
...
Type inputType = typeof(EntityType);
...
}
如果这样的话,将EntityType
作为一个泛型类型参数而不是一个常规输入参数并没有什么好处,反而会在您不知道输入类型时增加笨拙和缓慢的反射需求。
Duplicate() 函数的确切功能还不太清楚,但以下示例在您想要传递给 Duplicate() 的类型为类或整数时有效。
本质上,不要传入类型,而是传入一个示例对象。此测试方法说明了调用(一个方法中的两个测试)。
[TestMethod]
public void TestMethod1()
{
var myObject = new AnObject { AString = "someString" };
var myOtherObject = new AnotherObject();
var newObject = myObject.Duplicate(myOtherObject);
Assert.IsTrue(newObject.AString=="someString");
var newObject2 = myObject.Duplicate(1);
Assert.IsTrue(newObject2 is Int32);
}
Duplicate() 方法有一个与示例对象相关联的类型参数,但不需要使用给定的类型作为参数调用它,它会从示例对象中推断出来。
这是一个带有 Duplicate() 方法的类:
public class AnObject
{
public string AString { get; set; }
public T Duplicate<T>(T exampleObject)
where T: new()
{
var newInstance = (T)Activator.CreateInstance<T>();
// do some stuff here to newInstance based on this AnObject
if (typeof (T) == typeof (AnotherObject))
{
var another = newInstance as AnotherObject;
if(another!=null)
another.AString = this.AString;
}
return newInstance;
}
}
public class AnotherObject
{
public string AString { get; set; }
}
当传入的类型是值类型例如 int 时,这段代码可能在 Duplicate() 方法内部存在一些问题。具体取决于您想让 Duplicate() 对 int 做什么操作(您可能需要将其作为可空 int 传递)。
对于引用类型(类),它能够很好地运行。
myobject.Duplicate(myType);
或者你可以尝试使用反射,类似于:
System.Reflection.MethodInfo mi = typeof(TypeOfMyObject).GetMethod("Duplicate<>");
MethodInfo constructedMethodInfo = mi.MakeGenericMethod(new type[] {myType});
constructedMethodInfo.Invoke(myObject, new object[] {});
MethodInfo.Invoke
方法曾经有一个重载(如果不是唯一的),它只需要一个参数,但现在情况已经不同了。如果要调用的方法不需要任何参数,我们需要至少传递null
。还有另一种情况,可能会有Duplicate
方法的重载,这将抛出AmbiguousMatchException异常。我相信你知道这个,但我还是想加上我的两分钱。 - Mikayil Abdullayevnull
参数。 - Jon Skeet