Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/visual-studio-2012/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以传递父对象并在函数的另一侧重建它吗?_C#_Visual Studio 2012_Types - Fatal编程技术网

C# 我可以传递父对象并在函数的另一侧重建它吗?

C# 我可以传递父对象并在函数的另一侧重建它吗?,c#,visual-studio-2012,types,C#,Visual Studio 2012,Types,使用这些类 public class Parent { public int parentInt; } public class Child: Parent { public string childString; public Child(string passedString, int passedInt) { childString = passedString parentInt = passedInt } } 我

使用这些类

public class Parent
{
   public int parentInt;
}

public class Child: Parent
{
   public string childString;

   public Child(string passedString, int passedInt)
   {
       childString = passedString
       parentInt = passedInt
   }     
}
我想写一个函数,它可以实现如下功能:

public static void DoSomething(Parent passedParent, Type passedChildType)
{
    ScreenRecorder.Start()
    //print all of parents properties
    //print all of the specific child's properties if possible

}
我希望这个函数能够处理我将来创建的任何类型的子函数,如何使它能够在函数中动态地重建子函数的属性

下面是正在调用的方法的示例:

public static int dostuff(string s)
{
    int functionReturnValue = 0;

    switch (s)
    {
        case "":
            functionReturnValue = 0;
            break;
        case "7/8":
            functionReturnValue = 14;
            break;
        case "15/16":
            functionReturnValue = 15;
            break;
        default:
            Child ex = new Child("Blue", 1);
            Library.Handler.Process(ex, typeof(Child));
            break;
    }
    return functionReturnValue;
}
我可以在Dosomething方法中传入或执行什么操作来重建子对象属性?

方法1:消息字典 我认为,最好的方法是用一个简单的字典替换
父类
子类
,这样就可以根据需要包含任意数量的属性。这可以很容易地进行迭代,并在消息中包含您需要的任何信息


方法2:接口 与其让您的
过程
方法将类型作为参数,我建议将其设置为泛型-约束为
IParent
。呼叫变为:

Library.Handler.Process(ex);
声明为:

public void Process<TMessageType>(T message) where TMessageType : IParent
{
  ScreenRecorder.Start();
  message.Print();
}
public void进程(T message),其中TMessageType:IParent
{
ScreenRecorder.Start();
message.Print();
}
如上所述,iPart接口将包括一个名为
Print
的方法,该方法在基本父类中将打印您在上面定义的ParentInt属性,并根据需要进行格式化。然后,子对象将看起来和现在一样,并对
Print
进行额外的覆盖

这允许您在大多数情况下保持当前结构


方法3:反思 第三,最糟糕的方法是按现状使用当前的结构,并对物业进行反思。您的
DoSomething
方法将变得一团糟,并且可能相当缓慢(可能不重要)。这需要最少的重新设计,但代价是代码相当糟糕



这些方法中的任何一种都可以,但我必须强调,它们呈现的顺序与它们的质量有很大关系。

来回答实际提出的问题。是的,您可以在另一侧“重建”对象

有关示例,请参见此代码:

public class Parent
{
    int thing = 1;
}


public class Child1 : Parent
{
    public string name;

    public Child1(string p)
    {
        this.name = p;
    }
}

public class Child2 : Parent
{
    public string name;

    public Child2(string p)
    {
        this.name = p;
    }
}
在这个函数中,我们设置一个Child1对象并将其传递给另一个函数

    private void SetupStuff
    {
        Child1 x = new Child1("Bob");

        DoStuff(x);
    }
在这里,我们可以接收并“重建”

消息框将显示“Bob”

但请注意,这将导致运行时错误:

    private void DoStuff(Parent obj)
    {
        Child2 rebuiltObject = ((Child2)obj);
        MessageBox.Show(rebuiltObject.name);
    }

它足够聪明,可以防止您将对象重新构建为从未有过的对象。

异常表明发生了异常情况。他们应该被扔到发生的地方。同意法师的说法。抛出异常。您可以在
catch
处理程序中调用函数。您不必“重建”
Exception
对象,因为您将获得传递给您的原始对象&所有
Exception
类都是从
Exception
派生的。这就是多态性的作用。如果我以后决定让我的程序尝试优雅地处理它,而不告诉用户它的存在,并希望它继续工作,该怎么办?而不是现在我想让它爆炸的地方。如何使这种行为动态化?您应该研究面向方面的编程。您可以通过处理程序传递所有方法,并在一个位置管理异常类型。至于最后一句话,你永远不希望它爆炸。捕获错误并根据需要重新抛出,但请先处理它。请不要将异常转换为错误代码。发明异常是为了替换错误代码,而不是降低它们的级别。对异常进行了实质性的重组,并添加了更多的细节。以前不确定它是否值得被否决(尽管承认它不是很好),但现在肯定更好了。这并不能真正回答OP的问题。你只是告诉他如何将信息发送到另一个函数,而不是如何重建对象。@jth41:我的回答考虑了他实际提出的问题。他最近在问题中隐藏了一些细节,希望有人能让他使用异常作为消息。因为他实际上是在问如何传递信息,所以我的回答完全准确。同样,它也不需要你知道每一个可能的儿童类才能使用它。这是一个比我更糟糕的答案。这只是一个运行时演员阵容。我的回答是关于问题的完整背景和它的问题域,而不是帮助他错误地使用例外。尽管我肯定会承认这回答了问题,因为它现在已经被编辑过了。我唯一的抱怨是,它有助于完成任何一个理智的开发人员都不会做的事情,这是OP的错,而不是你的错。
    private void DoStuff(Parent obj)
    {
        Child2 rebuiltObject = ((Child2)obj);
        MessageBox.Show(rebuiltObject.name);
    }