在运行时保持功能更改对象类型

如何解决在运行时保持功能更改对象类型

| 长话短说 说我有以下代码
// a class like this 
class FirstObject {
    public Object OneProperty {
        get;
        set;
    }

    // (other properties)

    public Object OneMethod() {
        // logic
    }
}

// and another class with properties and methods names 
// which are similar or exact the same if needed 
class Secondobject {
    public Object OneProperty {
        get;
        set;
    }

    // (other properties)

    public Object OneMethod(String canHaveParameters) {
        // logic
    }
}

// the consuming code would be something like this 
public static void main(String[] args) {
    FirstObject myObject=new FirstObject();

    // Use its properties and methods
    Console.WriteLine(\"FirstObject.OneProperty value: \"+myObject.OneProperty);
    Console.WriteLine(\"FirstObject.OneMethod returned value: \"+myObject.OneMethod());

    // Now,for some reason,continue to use the
    // same object but with another type
    // -----> CHANGE FirstObject to Secondobject HERE <-----

    // Continue to use properties and methods but
    // this time calls were being made to Secondobject properties and Methods
    Console.WriteLine(\"Secondobject.OneProperty value: \"+myObject.OneProperty);
    Console.WriteLine(\"Secondobject.OneMethod returned value: \"+myObject.OneMethod(oneParameter));
}
是否可以将“ 1”类型更改为“ 2”并继续使用其属性方法? 我完全控制
FirstObject
,但是
Secondobject
已密封,完全超出了我的范围! 我可以通过反思来实现吗?怎么样?您如何看待要做的工作?显然,这两个类都比上面的示例复杂得多。 两个类都可以有
FirstObject<T>
Secondobject<T>
之类的模板,这让我感到难以使用反射来完成此类任务! 现实中的问题 为了简化起见,我试图以一种更简单的方式陈述我的问题,并尝试提取一些知识来解决它,但是,通过寻找答案,对我来说显而易见的是,要帮助我,您需要了解我真正的问题是,更改对象类型只是冰山一角。 我正在开发工作流程定义API。主要目标是使API能够在我可能要使用的任何引擎(CLR到WF4,NetBPM等)之上重用。 现在,我正在编写中间层,以将该API转换为WF4,以通过CLR运行工作流。 我已经完成的工作 在这个阶段,API概念与WF4相似,其中WF7具有with7ѭ,其中In / Out
Arguments
Data
Variables
)使用其参数贯穿through7ѭ。 伪代码中非常简化的API:
class Argument {
    object Value;
}

class Data {
    String Name;
    Type ValueType;
    object Value;
}

class ActivityState {
    String DescriptiveName;
}

class MyIf: ActivityState {
    InArgument Condition;
    ActivityState Then;
    ActivityState Else;
}

class MySequence: ActivityState {
    Collection<Data> Data;
    Collection<ActivityState> Activities;
}
我最初将其转换为WF4的方法也是通过
Activitiesstates
图进行的,并以某种方式直接分配属性,并在需要时使用反射。 再次简化伪代码,类似于:
new Activities.If() {
    displayName=myIf.DescriptiveName,Condition=TranslateArgumentTo_WF4_Argument(myIf.Condition),Then=TranslateActivityStateto_WF4_Activity(myIf.Then),Else=TranslateActivityStateto_WF4_Activity(myIf.Else)
}

new Activities.Sequence() {
    displayName=mySequence.DescriptiveName,Variables=TranslateDataTo_WF4_Variables(mySequence.Variables),Activities=TranslateActivitiesstatesTo_WF4_Activities(mySequence.Activities)
}
翻译结束时,我将有一个可执行的
System.Activities.Activity
对象。我已经很容易做到了。 大问题 当我开始将“ 9”对象转换为“ 17”时,这种方法出现了一个大问题。问题是WF4将工作流执行与上下文分开。因此,
Arguments
Variables
都是
LocationReferences
,必须通过
var.Get(context)
函数进行访问,引擎才能知道它们在运行时的位置。 使用WF4可以很容易地完成这样的事情:
Variable<string> var1=new Variable<string>(\"varname1\",\"string value\");
Variable<int> var2=new Variable<int>(\"varname2\",123);

return new Sequence {
    Name=\"Sequence Activity\",Variables=new Collection<Variable> { var1,var2 },Activities=new Collection<Activity>(){
        new Write() {
            Name=\"WriteActivity1\",Text=new InArgument<string>(
                context => 
                    String.Format(\"String value: {0}\",var1.Get(context)))
        },new Write() {
            //Name = \"WriteActivity2\",Text=new InArgument<string>(
                context => 
                    String.Format(\"Int value: {0}\",var2.Get(context)))
        }
    }
};
但是如果我想通过我的API代表相同的工作流程:
Data<string> var1=new Data<string>(\"varname1\",\"string value\");
Data<int> var2=new Data<int>(\"varname2\",123);

return new Sequence() {
    DescriptiveName=\"Sequence Activity\",Data=new Collection<Data> { var1,Activities=new Collection<ActivityState>(){
        new Write() {
            DescriptiveName=\"WriteActivity1\",Text=\"String value: \"+var1 // <-- BIG PROBLEM !!
        },new Write() {
            DescriptiveName=\"WriteActivity2\",Text=\"Int value: \"+Convert.ToInt32(var2) // ANOTHER BIG PROBLEM !!
        }
    }
};
当将
Data
对象用作
Variable
时,我遇到了一个大问题。我真的不知道如何允许开发人员使用我的API在任何需要的地方使用
Data
对象(就像WF4中一样),然后将
Data
转换为
System.Activities.Variable
解决方案浮现在脑海 如果您现在了解我的问题,
FirstObject
Secondobject
分别是
Data
System.Activities.Variable
。就像我说的那样,将ѭ9转换为ѭ25只是冰山一角,因为我可能在代码中使用ѭ35,并且在执行翻译时不知道如何将其转换为ѭ36。 我尝试过或想到的解决方案: 解决方案1 代替直接转换属性,我将为每个流控制活动(
If
Sequence
Switch
,...)开发
NativeActivites
,并利用
CacheMetadata()
函数指定
Arguments
Variables
。问题仍然存在,因为它们都可以通过
var.Get(context)
访问。 解决方案2 给我的
Data
类自己的
Get()
函数。它只是一个抽象方法,内部没有逻辑,它将以某种方式转换为ѭ17的
Get()
函数。使用C#甚至可能吗?可能不会!另一个问题是ѭ49具有一个参数。 解决方案3 我想到的最糟糕的解决方案是50英镑。尝试将使用
Data/Argument
代码替换为
Variable/Argument
代码。这对我来说就像一场噩梦。我对ѭ53几乎一无所知,即使我了解了它,我的猜测也是要花很多时间……甚至可能做不到。 抱歉,如果我最终提出了一个更大的问题,但是我真的被困在这里,迫切需要小费/继续前进的道路。     

解决方法

这被称为“鸭子打字”(如果它看起来像鸭子,而象鸭子一样的嘎嘎叫声,则可以像在鸭子上一样调用它的方法)。将myObject声明为动态的,而不是特定的类型,然后您应该会很好。 编辑:要清楚,这需要.NET 4.0
dynamic myObject = new FirstObject();
// do stuff
myObject = new SecondObject();
// do stuff again
    ,反思并不一定是正确的任务。如果无法控制
SecondObject
,则最好的选择可能只是使用扩展方法实例化该文件的新副本,然后逐个属性地复制数据。 您可以在复制过程中使用反射,然后以这种方式工作,但这确实是一个单独的问题。     

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?