代码之家  ›  专栏  ›  技术社区  ›  Wannabe

写出特定于派生类的财产

  •  0
  • Wannabe  · 技术社区  · 10 年前

    我需要确定我的代码在某一点上使用的是哪个对象,并只写出特定于该类的财产。我想不出怎么做。我被告知我能做,但我想不出来。有人能告诉我如何确定我正在使用的对象,并只为该类编写特定的财产吗?

    我已经看过其他问题,但我不够聪明,不适合我的例子。

    下面,我重新创建了一个我正在使用的代码示例。我可以看到所有的代码,但我只能在一个方法中工作(在这个示例中称为“MethodIAmWorkingIn”)。只有我可以用这种方法进行修改。

    public class Program
    {
    static void Main(string[] args)
    {
        TestDetailsAndResultsContainer container = new TestDetailsAndResultsContainer();
    
        DerivedClass1 derivedClass1 = new DerivedClass1();
        derivedClass1.DerivedClass1Prop1 = "DerivedClass1Prop1";
        derivedClass1.DerivedClass1Prop2 = "DerivedClass1Prop2";
    
        DerivedClass2 derivedClass2 = new DerivedClass2();
        derivedClass2.DerivedClass2Prop1 = "DerivedClass2Prop1";
        derivedClass2.DerivedClass2Prop2 = "DerivedClass2Prop2";
    
        container.TestDetails.Add(derivedClass1);
        container.TestDetails.Add(derivedClass2);
    
        TestResult testResult = new TestResult();
        testResult.TestResultProp1 = "TestResultProp1";
        testResult.TestResultProp2 = "TestResultProp2";
    
        container.Data.Add(testResult);
    
        Program p = new Program();
        p.MethodIAmWorkingIn(container);
    }
    
    private void MethodIAmWorkingIn(TestDetailsAndResultsContainer container)
    {
        // I need to see if the container variable holds a DerivedClass1 or DerivedClass2 object.
        foreach (var result in container.TestDetails)
        {
            var classINeedToDetermine = container.TestDetails.FirstOrDefault(m => m.TestDetailsProp1 == result.TestDetailsProp1);
    
            if (classINeedToDetermine is DerivedClass1)
            {
                classINeedToDetermine = result as DerivedClass1;
            }
            else if (classINeedToDetermine is DerivedClass2)
            {
                classINeedToDetermine = result as DerivedClass2;
            }
    
            // Now I need to use the classINeedToDetermine object and write its specific properties.
            // ???????????????????? I am stuck at this point ??????????????????
    
            // I need to write one or the other below. Can this be done?
    
            // If it is DerivedClass1, I need to write out those properties only.
            Console.WriteLine(classINeedToDetermine.DerivedClass1Prop1);
            Console.WriteLine(classINeedToDetermine.DerivedClass1Prop2);
    
            // OR
    
            // If it is DerivedClass2, I need to write out those properties only.
            Console.WriteLine(classINeedToDetermine.DerivedClass2Prop1);
            Console.WriteLine(classINeedToDetermine.DerivedClass2Prop2);
        }
    }
    }
    
    public class TestDetailsAndResultsContainer
    {
    public TestDetailsAndResultsContainer()
    {
        this.Data = new List<TestResult>();
        this.TestDetails = new List<TestDetails>();
    }
    
    public List<TestDetails> TestDetails { get; set; }
    
    public List<TestResult> Data { get; set; }
    }
    
    public abstract class TestDetails
    {
    public string TestDetailsProp1 { get; set; }
    public string TestDetailsProp2 { get; set; }
    }
    
    public class TestResult
    {
    public string TestResultProp1 { get; set; }
    public string TestResultProp2 { get; set; }
    }
    
    public class DerivedClass1 : TestDetails
    {
    public string DerivedClass1Prop1 { get; set; }
    public string DerivedClass1Prop2 { get; set; }
    }
    
    public class DerivedClass2 : TestDetails
    {
    public string DerivedClass2Prop1 { get; set; }
    public string DerivedClass2Prop2 { get; set; }
    }
    
    3 回复  |  直到 10 年前
        1
  •  2
  •   Blorgbeard    10 年前

    这个 as 关键字并不像你想象的那样。

    你的 classINeedToDetermine 是类型的变量 TestDetails 。您可以为其分配子类实例,但仍然无法通过该变量访问子类特定的财产。

    您只需要一些范围:

    if (classINeedToDetermine is DerivedClass1)
    {
        var derived1 = (DerivedClass1)result;
        Console.WriteLine(derived1.DerivedClass1Prop1);
        // etc      
    }
    else if (classINeedToDetermine is DerivedClass2)
    {
        var derived2 = (DerivedClass2)result;
        Console.WriteLine(derived2.DerivedClass2Prop1);
        // etc   
    }
    

    但这种事情维持下去并不有趣。

    另一种方法是使用多态性: 测试详细信息 类可以定义一个名为 PrintProperties ,并且所有子类都可以实现它。

    那你只要打电话 打印属性 而不用担心它们是哪个子类。

        2
  •  2
  •   Matthew Haugen    10 年前

    我不完全确定这里的对象是什么意思,但应该是这样的:

    foreach(var v in result.GetType().GetProperties())
    {
        if(v.DeclaringType == result.GetType())
        {
            Console.WriteLine(v.GetValue(result));
        }
    }
    

    再次,我不完全清楚你的用法 classINeedToDetermine result ,但您可以根据自己的需要进行更改。我选择了 后果 作为我的榜样 类需要确定 被你的那部分代码为空。

    顺便说一下,这部分代码是多余的。为了清晰和高效,应将其移除。

    if (classINeedToDetermine is DerivedClass1)
    {
        classINeedToDetermine = result as DerivedClass1;
    }
    else if (classINeedToDetermine is DerivedClass2)
    {
        classINeedToDetermine = result as DerivedClass2;
    }
    

    编辑:

    另一方面,如果性能对您来说比可伸缩性更重要(请阅读:如果您知道或控制所有要处理的类),您可以使用 is 我不喜欢用这个词“通用”

    if (classINeedToDetermine is DerivedClass1)
    {
        var typed = (DerivedClass1)result;
    
        Console.WriteLine(typed.DerivedClass1Prop1);
        Console.WriteLine(typed.DerivedClass1Prop2);
    }
    else if (classINeedToDetermine is DerivedClass2)
    {
        var typed = (DerivedClass2)result;
    
        Console.WriteLine(typed.DerivedClass2Prop1);
        Console.WriteLine(typed.DerivedClass2Prop2);
    }
    
        3
  •  0
  •   Philip Pittle    10 年前

    您可以使用 Type.GetProperties 为您的班级获取所有财产。然后你需要得到 MethodInfo 对于Get方法,通过 GetMethod .

    一旦您拥有 方法信息 你可以打电话 Invoke ,传入派生类。您可以先写入,然后将结果写入控制台。