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#基于值而不是引用调度扩展方法的主要内容,如果未能解决你的问题,请参考以下文章

C#之项目常用方法之静态扩展

仅将 ArrayList 作为值而不是引用传递

.net:C#的委托

this(C# 参考)

pandas 基于值而不是计数的窗口滚动计算

pandas 基于值而不是计数的窗口滚动计算