2010-05-10 5 views
9

Tôi đã ấn tượng rằng trình biên dịch C# sẽ ngầm loại một mảng dựa trên một kiểu mà tất cả chúng có thể được chuyển đổi hoàn toàn.Nhập một cách ngầm định các mảng thực hiện các giao diện

Trình biên dịch tạo ra Không loại tốt nhất tìm thấy cho mảng ngầm, đánh máy

public interface ISomething {} 

public interface ISomething2 {} 

public interface ISomething3 {} 

public class Foo : ISomething { } 
public class Bar : ISomething, ISomething2 { } 
public class Car : ISomething, ISomething3 { } 

void Main() 
{ 
    var obj1 = new Foo(); 
    var obj2 = new Bar(); 
    var obj3 = new Car(); 

    var objects= new [] { obj1, obj2, obj3 }; 
} 

Tôi biết rằng việc chỉnh sửa này là để khai báo kiểu như:

new ISomething [] { obj1, ...} 

Nhưng tôi 'm sau khi dưới một loại bao gồm giúp đỡ ở đây.

+0

như trong lý do tại sao các trình biên dịch không cố gắng tìm một loại phù hợp? –

Trả lời

14

Trình biên dịch C# xem xét tập các loại của tất cả các phần tử được chỉ định. Nó không xem xét các loại cơ sở chung, vv

Bạn thể đúc một trong những biểu hiện:

var objects= new [] { obj1, obj2, (ISomething) obj3 }; 

... nhưng cá nhân tôi muốn chỉ cần sử dụng các hình thức rõ ràng:

var objects= new ISomething[] { obj1, obj2, obj3 }; 

Hoặc, nếu bạn tuyên bố rõ ràng bất kỳ hoặc tất cả obj1, obj2obj3 làm loại ISomething, điều đó sẽ cũng làm việc tốt mà không thay đổi biểu thức khởi tạo mảng.

Từ C# 3 spec, phần 7.5.10.4:

Một biểu thức tạo mảng có dạng thứ ba được gọi là một ngầm gõ tạo mảng biểu. Nó tương tự như hình thức thứ hai , ngoại trừ phần tử loại của mảng không rõ ràng đã cho, nhưng được xác định là tốt nhất loại phổ biến (§7.4.2.13) của tập hợp các biểu thức trong bộ khởi tạo mảng.

Mục 7.4.2.13 trông như sau:

Trong một số trường hợp, một loại phổ biến cần phải được suy ra cho một tập hợp các biểu thức. Cụ thể, các loại phần tử của mảng được nhập hoàn toàn và trả về các chức năng ẩn danh với các đối tượng khối được tìm thấy theo cách này. trực giác, được đưa ra một tập hợp các biểu thức E1 ... Em suy luận này nên tương đương với gọi một phương thức

Tr M<X>(X x1 … X xm) 

với Ei như các đối số.Nhiều hơn chính xác, suy luận bắt đầu ra với biến kiểu chưa được trộn X. Suy luận kiểu đầu ra sau đó được thực hiện từ mỗi Ei với loại X. Cuối cùng, X được cố định và loại kết quả S là . biểu thức.

3

Nếu trường hợp tất cả có thể được truyền sang loại của bất kỳ một cá thể nào, thì loại đó sẽ được sử dụng. Nó không đủ cho tất cả các trường hợp có bất kỳ kiểu chung nào, nếu không khởi tạo mảng implicity sẽ luôn thành công và thường tạo ra các mảng không mong muốn new object[].

0

Như là một bổ sung nhỏ để trả lời của nhà Skeet:

Bạn có thể đúc một trong các mục mảng để loại bạn cần (giao diện trong trường hợp này) hoặc nếu bạn có chỉ là một yếu tố duy nhất của loại hình đó (không xuất phát mà là loại trực tiếp). Chẳng hạn như

public static IWindsorInstaller[] MobileRestComponentInstallers 
     { 
      get 
      { 
       return new [] 
          { 
           new RepositoryInstaller(), 
           new AppSettingsInstaller(), 
           // tens of other installers... 
           GetLoggerInstaller() // public IWindsorInstaller GetLoggerInstaller()... 
          }; 
      } 
     } 

này sẽ làm việc, nhưng xin đừng làm điều đó :) Chỉ cần xác định kiểu mảng và thay đổi new[]-new IWindsorinstaller[]. Dễ đọc hơn nhiều khi loại mảng được xác định rõ ràng.

0
Do like this for Class object(UIViewController) initialization in var array: 



var page1 = new Class1(); 
var page2 = new Class2(); 
var pages = new UIViewController[] { page1, page2 }; 

Lưu ý: đây UIViewController thể được bất kỳ lớp