扩展方法调用:
我们可以把外部扩展方法理解为一个特定静态类,虽然在IDE中,扩展方法能被参数对象直接调用,实际上它本质的方法地址还是存储在外部扩展类上。因此,如果你想通过被继承的类去获取扩展方法名称是获取不到的。
public
class
TestA
public
string
Name {
get
;
set
; }
public
static
class
TestAExt
public
static
void
Set(
this
TestA obj,
string
txt)
obj.Name = txt;
直接在对象中调用扩展方法:
void
test2()
TestA t =
new
TestA() { Name =
"BBBBBB"
};
t.Set(
"CCCCC"
);
如上代码,如果你想从中
typeof
(TestA).GetMethods
是
无法获得Set方法的。
只能通过
typeof
(TestAExt).GetMethods
获得,
并发射调用。
static
void
test2()
TestA t =
new
TestA() { Name =
"BBBBBB"
};
//t.Set("CCCCC");
var
mt=
typeof
(TestAExt).GetMethod(
"Set"
);
mt.Invoke(t,
new
object
[] { t,
"CCCCC"
});
Console.WriteLine(t.Name);
泛型方法的调用,需要遵循以下操作:
新增一个TestB类,建立泛型方法:
public
static
class
TestB
public
static
string
Get<
T
>(T obj)
if
(obj
is
TestA a)
return
a.Name;
return
null
;
反射调用示例:
static
void
test3()
TestA t =
new
TestA() { Name =
"ZZZZZ"
};
var
mt =
typeof
(TestB).GetMethod(
"Get"
);
var
mt2 = mt.MakeGenericMethod(
typeof
(TestA));
Console.WriteLine(mt2.Invoke(
null
,
new
object
[] { t }));
扩展泛型的反射调用
参考如下:
static void test0()
met = type.GetMethod("XXX");
var met2 = met.MakeGenericMethod(parm[0].GetType());
return met2.Invoke(null, parm);
泛型获取参数类:
GenericTypeArguments
比如,获取DbContext中的所有参数类:
DbContext.GetType().GetProperties().Where(q => q.PropertyType.IsGenericType && typeof(System.Data.Entity.DbSet<>).IsAssignableFrom(q.PropertyType.GetGenericTypeDefinition()))
static void Main(string[] args)
foreach (PropertyInfo pi in typeof(ClassLibrary2.Model2).GetProperties().Where(q => q.PropertyType.IsGenericType && typeof(System.Data.Entity.DbSet<>).IsAssignableFrom(q.PropertyType.GetGenericTypeDefinition())))
Console.WriteLine($"FullName:{pi.PropertyType.FullName}");
Console.WriteLine($"GetGenericTypeDefinition:{pi.PropertyType.GetGenericTypeDefinition()}");
Console.WriteLine($"IsConstructedGenericType:{pi.PropertyType.IsConstructedGenericType}");
Console.WriteLine($"IsGenericParameter:{pi.PropertyType.IsGenericParameter}");
Console.WriteLine($"IsGenericType:{pi.PropertyType.IsGenericType}");
Console.WriteLine($"IsGenericTypeDefinition:{pi.PropertyType.IsGenericTypeDefinition}");
Console.WriteLine($"=============GenericTypeArguments=============");
foreach (Type type in pi.PropertyType.GenericTypeArguments)
Console.WriteLine($"{type.FullName}");
if (pi.PropertyType.IsGenericParameter)
Console.WriteLine($"=============GetGenericParameterConstraints=============");
foreach (Type type in pi.PropertyType.GetGenericParameterConstraints())
Console.WriteLine($"{type.FullName}");
Console.ReadLine();
FullName:System.Data.Entity.DbSet`1[[ClassLibrary2.MyEntity20, ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
GetGenericTypeDefinition:System.Data.Entity.DbSet`1[TEntity]
IsConstructedGenericType:True
IsGenericParameter:False
IsGenericType:True
IsGenericTypeDefinition:False
=============GenericTypeArguments=============
ClassLibrary2.MyEntity20
FullName:System.Data.Entity.DbSet`1[[ClassLibrary2.MyEntity21, ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
GetGenericTypeDefinition:System.Data.Entity.DbSet`1[TEntity]
IsConstructedGenericType:True
IsGenericParameter:False
IsGenericType:True
IsGenericTypeDefinition:False
=============GenericTypeArguments=============
ClassLibrary2.MyEntity21
FullName:System.Data.Entity.DbSet`1[[ClassLibrary2.MyEntity22, ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
GetGenericTypeDefinition:System.Data.Entity.DbSet`1[TEntity]
IsConstructedGenericType:True
IsGenericParameter:False
IsGenericType:True
IsGenericTypeDefinition:False
=============GenericTypeArguments=============
ClassLibrary2.MyEntity22
FullName:System.Data.Entity.DbSet`1[[ClassLibrary2.MyEntity23, ClassLibrary2, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]
GetGenericTypeDefinition:System.Data.Entity.DbSet`1[TEntity]
IsConstructedGenericType:True
IsGenericParameter:False
IsGenericType:True
IsGenericTypeDefinition:False
=============GenericTypeArguments=============
ClassLibrary2.MyEntity23