2011-10-08 70 views
2

我有一个病人类:我可以像这样工作吗?

class Patient { 
    public string First_Name { get; set; } 
    public string Last_Name { get; set; } 
    public DateTime Date_of_Birth { get; set; } 
} 

我也有一个接口:

interface IPerson { 
    string First_Name { get; } 
    string Last_Name { get; } 
} 

在这个控制台应用程序,我想Display_Person方法工作。它编译但会引发运行时错误,因为Patient不执行IPerson。

class Program { 
    static void Main(string[] args) { 
    Patient p = new Patient { 
     First_Name = "Charles", Last_Name = "Lambert", 
     Date_of_Birth = new DateTime(1976,5,12), 
    }; 
    Display_Person(p); 
    } 

    static void Display_Person(dynamic person) { 
    IPerson p = person; 
    Console.WriteLine("{0}, {1}", p.Last_Name, p.First_Name); 
    } 
} 

什么样的代码改变,没有Patient实现IPerson接口,我可以让Display_Person方法工作吗?我更喜欢可重用的解决方案。

更新:我想这个工作,所以我可以得到intellisense。请看看这个例子的微不足道。它简短并重点解释我的问题。如果这是1003贷款申请(打印时是一本书的大小),我不想将20+个接口应用于我的课程,因此我可以将相关数据分组计算。我也不希望每次都输出所有这些属性。缺乏智能感使我不再使用过去的动态语言。 (我不是懒惰,我很高效!)

+0

如果你确实想让intellisense工作,就像你在例子中那样使用它,摆脱IPerson行并将'person'参数改为'p'。不理想,但智能只知道你的代码允许。 –

回答

4

您可以使用Impromptu Interface来做到这一点。

+0

像你的建议一样酷。它不适用于非公共接口。另外如果动态类型实际上是一个定义的类型,就像我的Patient类一样。它会抛出一个运行时错误,“Patient”不执行'ActLike()'方法。 –

+0

这很奇怪,我已经广泛地使用它来将动态对象强制转换为接口。你是否尝试了另一种语法:'Impromptu.ActLike (expando);'? –

+0

如果它是公开的,它工作正常。 'dynamicVariableName.ActLike ()'根本不起作用。 'Impromptu.ActLike ()仅在接口公开时才起作用。我想它不能反映内部成员。 –

0

不!我认为(没有实施IPatient)是可能的。你必须实现IPatient接口

class Patient : IPatient {} 

或者删除铸造。

static void Display_Person(dynamic person) 
{ 
    Console.WriteLine("{0}, {1}", person.Last_Name, person.First_Name); 
} 
3

如果你真的使用动态,那么为什么转换?

static void Display_Person(dynamic person) { 
    Console.WriteLine("{0}, {1}", person.Last_Name, person.First_Name); 
} 

但是,如果病人执行IPerson,我仍然会更喜欢。从设计的角度来看,它会更有意义,类型安全意味着在编译时而不是运行时捕获任何错误。

0

IPerson是不必要的。只是做Display_Person这样的:

static void Display_Person(dynamic person) { 
    Console.WriteLine("{0}, {1}", person.Last_Name, person.First_Name); 
} 

只要person实现这些属性,这工作正常。