2013-04-25 41 views
6

Nói rằng tôi có các lớp sau:Làm thế nào để biến một thể hiện Động vật thành một cá thể Dog?

class Animal 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
} 

class Dog:Animal 
{ 
    public void sniffBum() 
    { 
     Console.WriteLine("sniff sniff sniff"); 
    } 
} 

Nếu tôi có một thể hiện của Animal, làm thế nào để bỏ nó vào một Dog? Một cái gì đó như thế này:

Animal a = new Animal(); 
if (some logic to determine that this animal is a dog) 
{ 
    Dog d = (Dog)a; 
    d.sniffBum(); 
} 

Về cơ bản tôi không thể sử dụng giao diện. Tôi sẽ luôn có một đối tượng Animal sắp ra khỏi cơ sở dữ liệu của tôi như thế. Dog không có bất kỳ tham số nào nhiều hơn Animal, chỉ có các phương thức mới.

Tôi chỉ có thể tạo đối tượng Dog mới và chuyển các giá trị trên, (hoặc có một hàm tạo có loại Animal), nhưng điều này có vẻ lộn xộn.

+1

nếu tất cả các đối tượng là từ loại 'động vật 'bạn cần phải lưu Loại cũng trong cơ sở dữ liệu của bạn theo cách nào đó – WiiMaxx

+0

Có một hàm tạo có một tham số kiểu' Động vật' không phải là lộn xộn ở tất cả IMO – Kamyar

+0

là biến thể 'Animal'class của bạn? – WiiMaxx

Trả lời

2

Kiểm tra truyền sẽ không hoạt động nếu trường hợp Animal chưa bao giờ là một ví dụ Dog.

Bạn có thể muốn xem Decorator Pattern, điều này sẽ cho phép bạn thêm Dog phương thức vào ví dụ Animal. Về cơ bản, DogAnimal cả hai đều có giao diện IAnimal. Lớp Dog có một cá thể Animal trong hàm tạo và giữ tham chiếu nội bộ.Việc thực hiện của IAnimal chỉ đơn giản là giảm bớt đối với trường hợp tham chiếu Animal (cho phép Dog được truyền tới IAnimal và hoạt động giống như gói Animal cho đa hình). Dog cũng có các phương thức bổ sung dành riêng cho chó.

3

Để kiểm tra xem một đối tượng có thể được truyền sang loại sử dụng từ khóa is hay không.

Animal animal = new Dog(); 

if(animal is Dog) 
{ 
    //your code 
} 
+0

Xem tài liệu msdn về là nhà điều hành http://msdn.microsoft.com/en-us/library/scekt9xw(v=vs.71).aspx Toán tử được sử dụng để kiểm tra xem loại thời gian chạy của một đối tượng tương thích với một kiểu nhất định. –

+1

Tôi tò mò về lý do downvote – zerkms

+0

@zerkms tôi nữa. –

0

Tôi không làm việc như thế này. Truyền là một hoạt động mà diễn giải một phiên bản làm loại đã cho, nó sẽ không thay đổi loại của nó. Trong trường hợp của bạn, trước tiên bạn phải xác định loại động vật nào có trong hàng cơ sở dữ liệu cụ thể đó và sau đó khởi tạo tổ tiên chính xác. Giả:

var row = Fetch from database; 
Animal animal; 
if (row is a dog) animal = new Dog(); 
else if (row is a cat) animal = new Cat(); 
2

Bạn có thể làm điều đó với is, nhưng kể từ khi bạn sẽ muốn gọi một cái gì đó trên bất kỳ con chó bạn tìm thấy nó sẽ là tốt hơn để sử dụng as:

var dog = a as Dog; 
if (dog != null) 
{ 
    dog.sniffButt(); 
} 

Tuy nhiên bạn nên có nhận thức được rằng sự sắp xếp này (cố gắng xác định kiểu thời gian chạy của một giá trị để bạn có thể truyền nó đến một cái gì đó thuận tiện) thường bị cau mày khi có lý do chính đáng. Bạn có thể dễ dàng overdo nó và kết thúc kiểm tra cho chó, mèo, vẹt, cá, rùa ... Tôi chắc chắn bạn có thể hình dung mess kết quả.

Nếu nhu cầu của bạn hướng tới kịch bản đó, giải pháp tốt hơn nhiều là sử dụng mẫu thiết kế của Khách truy cập.

3

Đầu tiên tạo ra động vật như chó sau đó kiểm tra nếu nó is chó

Animal a = new Dog(); 
if (a is Dog) 
{ 
    Dog d = (Dog)a; 
    d.sniffBum(); 
} 
0

Bạn có thể làm điều này:

var dog = a as Dog; 
if(dog != null) 
{ 
    dog.DoSomething(); 
} 

nó là preffereable để kiểm tra nếu a là chó nếu bạn cần để cast nó sau. Xem câu trả lời sau: Casting vs using the 'as' keyword in the CLR

0

Bạn không thể bỏ một con vật vào một con chó, nó có thể là một con mèo! Tôi nghĩ rằng những gì bạn đang cố gắng đạt được là tạo ra một đối tượng thuộc loại Dog, từ một đối tượng khác thuộc loại Animal được lấy từ db.

Một cách là chấp nhận một đối tượng kiểu Animal trong Dog 's constructor quá tải:

class Dog:Animal 
{ 
    public Dog(Animal animal) 
    { 
     this.Id = animal.Id; 
     this.Name = animal.Name; 
    } 
... 
} 

Bằng cách này, bạn chỉ có thể sử dụng như sau:

if (some logic to determine that this animal is a dog) 
{ 
    Dog d = new Dog(a); 
    d.sniffBum(); 
} 
0

tôi sẽ tạo ra một số tĩnh các phương thức trên đối tượng Dog hoặc một số loại DogFactory nơi bạn có thể pas số Animal làm thông số và tạo nó cho Chó hoặc trả lại null.

Trong phương pháp mà bạn có thể làm kiểm tra trên các đặc tính động vật của bạn để xem nếu bạn muốn nó trở thành một con chó (4 chân, bit, bất cứ điều gì)

Nếu không nó sẽ là khó để đi từ một đối tượng được tạo ra như Animal đối tượng cụ thể Dog

1

Động vật không bao giờ là chó.

Làm cho trình tạo Con chó của bạn, lấy Tham số động làm thông số.

class Dog : Animal 
{ 
    public Dog(Animal a) 
    { 
     this.Name = a.Name; 
     this.Id = a.Id; 
    } 

    public void sniffBum() 
    { 
     Console.WriteLine("sniff sniff sniff"); 
    } 
} 
+0

+1. Đó là những gì OP đang cố gắng đạt được – Kamyar

0

Kamyar là đúng không có cách nào để làm điều này vì như bạn tự nói với chúng tôi

i will always have an Animal object coming out of my database like that 

vì vậy bạn cần phải lưu các loại cũng trong cơ sở dữ liệu của bạn

sau đó bạn nên thay đổi của bạn Animal đến

public class Animal 
{ 
    public long Id { get; set; } 
    public string Name { get; set; } 
    public string AnimalType { get; private set; } 

    public Animal() { } 
    public Animal(string type) 
    { 
     AnimalType = type; 
    } 

    // to denie self repeading if all animales have the same Properties 
    protected void set(Animal a) 
    { 
     Id = a.Id; 
     Name = a.Name; 
     AnimalType = a.AnimalType; 
    } 
} 

.

Dog doesnt have any more parameters than Animal has, only new methods 

để bạn có thể modifie bạn Dog để

public class Dog : Animal 
{ 
    public Dog(Animal a) 
    { 
     base.set(a); 
    } 

    public void sniffBum() 
    { 
     Console.WriteLine("sniff sniff sniff"); 
    } 
} 

.

i could just create a new Dog object, and pass the values accross, (...), but this just seems messy 

tôi không nghĩ rằng có một con đường xung quanh và nó không giống mà lộn xộn

và đây là làm thế nào để sử dụng ví dụ

 Animal a = new Animal("Dog"); 
     if (a.AnimalType =="Dog") 
     { 
      Dog d = new Dog(a); 
      d.sniffBum(); 
     } 
Các vấn đề liên quan