2012-05-08 37 views
7

Tôi muốn cung cấp tham số cho phương thức và tôi muốn phương thức của mình trả về dữ liệu bằng cách tìm tham số. Dữ liệu có thể ở dạng boolean, string, int hoặc etc. Làm thế nào tôi có thể trả về một kiểu biến từ một phương thức? Tôi không muốn trả về một kiểu đối tượng và sau đó chuyển nó sang kiểu khác. Ví dụ:Loại trả về biến của phương thức trong C#

BlaBla VariableReturnExampleMethod(int a) 
{ 
    if (a == 1) 
     return "Demo"; 
    else if (a == 2) 
     return 2; 
    else if (a == 3) 
     return True; 
    else 
     return null; 
} 

Lý do tôi muốn có phương pháp đọc cột được chọn của hàng từ cơ sở dữ liệu. Các loại cột không giống nhau nhưng tôi phải trả về thông tin của mỗi cột.

+2

trên ghi chú thay vì tất cả những điều này nếu elses tôi nói thực hiện một nghiên cứu nhỏ về chuyển đổi http://msdn.microsoft.com/en-us/library/06tc147t(v=vs.80). aspx – RhysW

+0

@RhysW +1 cho chuyển đổi, nhưng trong trường hợp này, 'else' không được yêu cầu,' if' sẽ đủ. –

+0

là u chắc chắn nếu bạn phải trả lại chỉ một vài loại tiêu chuẩn như int, chuỗi vv? hoặc là nó nhiều lớp học từ mã ur? – nawfal

Trả lời

13

Làm cách nào tôi có thể trả về loại biến từ phương pháp? Tôi không muốn trả về một kiểu đối tượng và sau đó chuyển nó sang kiểu khác.

Vâng, đó chính là điều bạn làm phải làm. Ngoài ra, nếu bạn đang sử dụng C# 4 bạn có thể làm các kiểu trả về dynamic, mà sẽ cho phép việc chuyển đổi để ngầm:

dynamic VariableReturnExampleMethod(int a) 
{ 
    // Body as per question 
} 

... 

// Fine... 
int x = VariableReturnExampleMethod(2); 

// This will throw an exception at execution time 
int y = VariableReturnExampleMethod(1); 

Về cơ bản, bạn chỉ định các loại để cho các trình biên dịch biết những gì mong đợi. Làm thế nào nó có thể hoạt động nếu loại chỉ được biết tại thời điểm thực hiện? Lý do phiên bản dynamic hoạt động là cơ bản bảo trình biên dịch trì hoãn hoạt động bình thường của nó cho đến thời gian thực hiện - vì vậy bạn mất an toàn bình thường để cho ví dụ thứ hai thất bại trong thời gian biên dịch.

+0

Tôi không biết, tôi đang chờ lời khuyên của bạn. – sanchop22

+0

@petre: Thật khó để đưa ra bất kỳ lời khuyên nào khác mà không biết tại sao bạn lại muốn làm điều này ngay từ đầu. –

+1

Tôi thích câu trả lời của Jon Skeet có ba +1 trong vòng 1 phút kể từ khi trả lời - ngay cả trước khi anh ấy nói thêm. Phải được tốt đẹp :) – Tim

4

Sử dụng dynamic Từ khóa thay vì BlahBlah nếu bạn đang nhắm mục tiêu .Net 4.0 nhưng nếu ít hơn thì object là đặt cược an toàn nhất vì đây là lớp cơ sở cho mọi lớp khác mà bạn có thể nghĩ đến.

0

Sử dụng loại trả lại là object, sau đó bạn có thể nhận bất kỳ loại trả lại nào. bạn phải xử lý kiểu trả về ether thông qua sự phản xạ hoặc phương thức khác.

việc kiểm tra này:

void Main() 
{ 
    object aa = VariableReturnExampleMethod(3); 
    Console.WriteLine(aa.ToString()); 
} 

object VariableReturnExampleMethod(int a) 
{ 
    if (a == 1) 
     return "Demo"; 
    else if (a == 2) 
     return 2; 
    else if (a == 3) 
     return true; 
    else 
     return null; 
} 

Edit: Tôi đang trong lợi của các đối tượng gõ mạnh và bạn có thể thực hiện nó một cách dễ dàng trên nền tảng .net.

if(returnedValue !=null) 
{ 

string currentDataType = returnedValue.GetType().Name; 
object valueObj = GetValueByValidating(currentDataType, stringValue); 
} 


public object GetValueByValidating(string strCurrentDatatype, object valueObj) 
     { 
      if (valueObj != "") 
      { 
       if (strCurrentDatatype.ToLower().Contains("int")) 
       { 
        valueObj = Convert.ToInt32(valueObj); 
       } 
       else if (strCurrentDatatype.ToLower().Contains("decimal")) 
       { 
        valueObj = Convert.ToDecimal(valueObj); 
       } 
       else if (strCurrentDatatype.ToLower().Contains("double") || strCurrentDatatype.ToLower().Contains("real")) 
       { 
        valueObj = Convert.ToDouble(valueObj); 
       } 
       else if (strCurrentDatatype.ToLower().Contains("string")) 
       { 
        valueObj = Convert.ToString(valueObj); 
       } 
       else 
       { 
        valueObj = valueObj.ToString(); 
       } 
      } 
      else 
      { 
       valueObj = null; 
      } 
      return valueObj; 
     } 
+0

Anh ấy đã yêu cầu một giải pháp không đúc – Crisfole

2

Có vẻ như đây có thể là trường hợp tốt cho generics. Nếu bạn biết bạn đang mong đợi kiểu dữ liệu nào khi gọi nó, bạn có thể gọi phiên bản chung của hàm đó.

+0

Mặc dù generics có thể trợ giúp trong các tình huống khác, nó đã thắng 't giúp đỡ trong tình hình được cung cấp bởi các OP * trừ khi * người gọi biết loại sẽ được trả lại bởi các đối số được cung cấp tại thời gian biên dịch ... không. –

+0

@Adam Houldsworth - Dựa trên mô tả của ông về vấn đề (thực tế là đây là một cuộc gọi trả về giá trị từ một cơ sở dữ liệu) có vẻ như mã gọi có thể thực sự biết những gì nó đang mong đợi. Có vẻ như anh ta có một hàm ReadFromDatabase (fieldname), và bạn có thể thực sự biết kiểu dữ liệu của trường trong trường hợp đó. Đó không phải là một thiết kế tốt, theo ý kiến ​​của tôi, nhưng Generics sẽ làm cho nó dễ dàng hơn. – Tim

+0

Hãy xem xét 'Field ' từ DataTable làm ví dụ về điều này. Các lựa chọn tốt duy nhất là điều này hoặc chỉ trở về đối tượng, và như OP loại trừ các tùy chọn khác, đây là những gì còn lại. – Servy

2

Cân nhắc sử dụng thứ gì đó như Dapper-dot-net (được viết bởi Marc Gravell và Sam Saffron tại Stack Overflow của chính chúng ta) để kéo mọi thứ ra khỏi DB. Nó xử lý cơ sở dữ liệu để ánh xạ đối tượng cho bạn.

Hơn nữa, nếu bạn không muốn sử dụng công cụ và bạn đang kéo từ Cơ sở dữ liệu và bạn biết các loại dữ liệu của các cột khác nhau tại thời điểm biên dịch (như bạn nghe) làm việc theo từng hàng thay vì từng cột.

//Pseudo-code: 
List<DatabaseObject> objects = new List<DatabaseObject>(); 
foreach(var row in DatabaseRows) 
{ 
    var toAdd = new DatabaseObject(); 
    toAdd.StringTypeVariable = "Demo"; 
    toAdd.IntTypeVariable = 2; 
    toAdd.BoolTypeVariable = true; 
    object.Add(toAdd); 
} 

Lưu ý: bạn có thể sử dụng cú pháp khởi tạo đối tượng và LINQ tại đây nhưng đây là cách cơ bản nhất tôi có thể nghĩ để giới thiệu điều này mà không cần sử dụng nhiều nội dung bổ sung.Cũng cần lưu ý rằng ở đây tôi giả định rằng bạn không thực sự là muốn trả về "Bản trình diễn", 2 và đúng, nhưng các giá trị sử dụng hàng đó. Điều đó chỉ có nghĩa là bạn muốn thay đổi các giá trị được mã hóa cứng thành: row.GetStringType(stringColumnIdx) hoặc một cái gì đó tương tự.

+0

+1 cho đề xuất cho từng hàng thay vì từng cột – Bob2Chiv

0

Tôi nhìn vào yêu cầu của bạn và câu hỏi tốt hơn giây, nhưng cuối cùng tôi phải viết lại để hiểu rõ hơn về giải pháp. Và giải pháp này bỏ qua lâu nếu ngăn xếp và thay thế nó bằng cách tìm kiếm trên các loại enum, nơi chúng ta có thể thực hiện tất cả các loại những gì chúng ta cần. Tôi giống như sử dụng năng động, nhưng điều này là có thể sử dụng quá.

Chức năng chính GetValueByValidating giá trị trả lại nếu là loại được xác định và có thể, trong những trường hợp khác trả về false Look Niranjan-kala đây là chức năng chính của bạn sau khi viết lại.



      /// 
     /// Enum of wanted types 
     /// 
     public enum Types 
     { 
      [ExtendetFlags("int")] 
      INT, 
      [ExtendetFlags("decimal")] 
      DECIMAL, 
      [ExtendetFlags("double")] 
      DOUBLE, 
      [ExtendetFlags("real")] 
      REAL, 
      [ExtendetFlags("string")] 
      STRING, 
      [ExtendetFlags("object")] 
      OBJECT, 
      [ExtendetFlags("null")] 
      NULLABLE 
     } 
     /// 
     /// Cycle by types when in enum exist string reference on type (helper) 
     /// 
     /// 
     /// 
     public static Types GetCurrentType(string container) 
     { 
      foreach (Types t in Enum.GetValues(typeof(Types))) 
      { 
       if (container.Contains(t.GetFlagValue())) 
       { 
        return t; 
       } 
      } 
      return Types.NULLABLE; 
     } 
     /// 
     /// Return object converted to type 
     /// 
     /// 
     /// 
     /// 
     public static object GetValueByValidating(string strCurrentDatatype, object valueObj) 
     { 
      var _value = valueObj != null ? valueObj : null; 
      try 
      { 
       Types _current = _value != null ? GetCurrentType(strCurrentDatatype.ToLower()) : Types.NULLABLE; 

       switch (_current) 
       { 
        case Types.INT: 
         valueObj = Convert.ToInt32(valueObj); 
         break; 
        case Types.DECIMAL: 
         valueObj = Convert.ToDecimal(valueObj); 
         break; 
        case Types.DOUBLE: 
         valueObj = Convert.ToDouble(valueObj); 
         break; 
        case Types.REAL: 
         valueObj = Convert.ToDouble(valueObj); 
         break; 
        case Types.STRING: 
         valueObj = Convert.ToString(valueObj); 
         break; 
        case Types.OBJECT: 
         break; 
        case Types.NULLABLE: 
         throw new InvalidCastException("Type not handled before selecting, function crashed by retype var."); 
       } 
      } catch (InvalidCastException ex) 
      { 
       Log.WriteException(ex); 
       valueObj = false; 
      } 

      return valueObj; 
     } 


+0

Đây là mã đã hứa của ExtendetFlags từ Enum: [ExtendetFlags Class] (http://stackoverflow.com/a/36173834/4689104) –

Các vấn đề liên quan