c#基于值而不是引用调度扩展方法
Posted
技术标签:
【中文标题】c#基于值而不是引用调度扩展方法【英文标题】:c# Dispatching Extension Methods based on Value not Reference 【发布时间】:2017-03-01 08:38:33 【问题描述】:给定以下 2 种扩展方法
public static string getIDPropertyName(this object value)
return "ID";
public static string getIDPropertyName<IDType>(this EntityRestIdentityDescriber<IDType> entityIdentityDescriber)
return entityIdentityDescriber.propertyNameDescribingID();
以及以下 2 次调用
//arrange
object test = new CustomEntityRestModelIdentity();
//test.UserName = "KKK";
//act
var actual = test.getIDPropertyName(); //calls the first extension method
var actual2 = (test as CustomEntityRestModelIdentity).getIDPropertyName(); //calls the second extension method
如何执行第二个扩展方法,即使它的引用类型是对象但它的值类型是 EntityRestIdentityDescriber?我正在寻找静态多态性。
【问题讨论】:
你的意思是不强制转换怎么调用它? 在编译时选择扩展方法。您已经在问题中找到了解决方法(实际 2)。 @AliSheikhNezami 这不是测试哈哈。我要做的是通过反射登陆一个对象,然后调用getIDPropertyName,以便在对象实现EntityRestIdentityDescriber的情况下获得正确的执行方法。如果对象没有实现它,它默认使用另一个返回 ID 的方法。没有强制转换或继承就没有办法调用其他方法吗? @buffjape 我不这样做是因为我由于反射而着陆了一个对象,并且想要执行另一个方法,以防对象在运行时实现 EntityRestIdentityDescriber 【参考方案1】:试试这个
public static string getIDPropertyName(this object entityIdentityDescriber)
if(entityIdentityDescriber is EntityRestIdentityDescriber<IDType>)
return entityIdentityDescriber.propertyNameDescribingID();
else
return "id";
【讨论】:
是的,我之前想过这样做,但是 IDType 是未定义的,所以我不能真正转换,因为我不知道运行时的值。我也不能删除 hte Generic 限制,因为它在其他地方是必需的。除了继承和动态多态,就没有别的办法了吗?【参考方案2】:你需要double dispatch
.Double dispatch
在运行时根据实际类型确定调度
public class IdPropertyNameResolver
public string GetIDPropertyName(object value)=>"ID";
public string GetIDPropertyName<T>(EntityRestIdentityDescriber<T> value)=>
value.propertyNameDescribingID();
//......do something
object o = new CustomEntityRestModelIdentity();
new IdPropertyNameResolver().GetIDPropertyName((dynamic)o);//CustomEntityRestModelIdentity id name
//......
【讨论】:
以上是关于c#基于值而不是引用调度扩展方法的主要内容,如果未能解决你的问题,请参考以下文章