Cách tốt hơn để truyền đối tượng vào int


179

Điều này có thể là tầm thường, nhưng tôi không thể nghĩ ra một cách tốt hơn để làm điều đó. Tôi có một đối tượng COM trả về một biến thể trở thành một đối tượng trong C #. Cách duy nhất tôi có thể có được điều này vào một int là

int test = int.Parse(string.Format("{0}", myobject))

Có cách nào sạch hơn để làm điều này? Cảm ơn

Câu trả lời:


362

Bạn có một vài lựa chọn:

  • (int)- Toán tử đúc. Hoạt động nếu đối tượng đã là một số nguyên ở một mức nào đó trong hệ thống phân cấp thừa kế hoặc nếu có một chuyển đổi ngầm định nghĩa.

  • int.Parse()/int.TryParse() - Để chuyển đổi từ một chuỗi định dạng không xác định.

  • int.ParseExact()/int.TryParseExact() - Để chuyển đổi từ một chuỗi trong một định dạng cụ thể

  • Convert.ToInt32() - Để chuyển đổi một đối tượng không xác định. Nó sẽ sử dụng một chuyển đổi rõ ràng và ẩn hoặc triển khai IConvertible nếu có bất kỳ được xác định.

  • as int?- Lưu ý "?". Các asnhà điều hành duy nhất là đối với các loại tài liệu tham khảo, và vì vậy tôi sử dụng "?" để biểu thị a Nullable<int>. Các " as" điều hành hoạt động giống như Convert.To____(), nhưng nghĩ TryParse()chứ không phải là Parse(): nó trả nullchứ không phải ném một ngoại lệ nếu chuyển đổi thất bại.

Trong số này, tôi thích (int)nếu đối tượng thực sự chỉ là một số nguyên được đóng hộp. Nếu không sử dụng Convert.ToInt32()trong trường hợp này.

Lưu ý rằng đây là một câu trả lời rất chung chung : Tôi muốn chú ý đến câu trả lời của Darren Clark vì tôi nghĩ rằng đó là một công việc tốt để giải quyết các chi tiết cụ thể ở đây, nhưng đã đến muộn và chưa được bình chọn. Dù sao, anh ta cũng nhận được phiếu bầu của tôi cho "câu trả lời được chấp nhận", vì cũng khuyến nghị (int), vì đã chỉ ra rằng nếu nó không (int)(short)thể hoạt động thay thế và để khuyên bạn nên kiểm tra trình gỡ lỗi của mình để tìm ra loại thời gian chạy thực tế.


Tôi đã tìm thấy một điểm không thực sự là một lỗi nhưng có lẽ đơn giản hóa mọi thứ quá nhiều để ai đó có thể nghĩ rằng. Tôi đã xóa câu đó và thêm một liên kết đến tài liệu có thẩm quyền.
Joel Coehoorn

Diễn viên trực tiếp sẽ làm việc với một chuyển đổi ngầm? Tôi có ấn tượng rằng sẽ chỉ thực hiện unboxing chứ không phải bất kỳ chuyển đổi nào khác.
Darren Clark

Không chính xác là một phản hồi, nhưng hãy đọc nó: blog.msdn.com/ericlippert/archive/2009/03/19/ mẹo
Joel Coehoorn

Kết quả cuối cùng là nó chắc chắn làm nhiều hơn là chỉ unbox. Nếu không, tại sao bạn có thể sử dụng nó để tạo một gấp đôi cho một int, ví dụ?
Joel Coehoorn

Và đọc một số thứ khác tôi có thể có ẩn của tôi / rõ ràng ngược lên đó - nhưng theo cách nào đó tôi nghĩ rằng nó có điểm chính.
Joel Coehoorn

41

Dàn diễn viên (int) myobject chỉ nên làm việc.

Nếu điều đó mang lại cho bạn một ngoại lệ cast không hợp lệ thì đó có thể là do loại biến thể không phải là VT_I4. Đặt cược của tôi là một biến thể với VT_I4 được chuyển đổi thành một hộp int, VT_I2 thành một hộp ngắn, v.v.

Khi thực hiện đúc trên một loại giá trị được đóng hộp, nó chỉ có giá trị để chuyển nó sang loại được đóng hộp. Ví dụ, nếu biến thể được trả về thực sự là VT_I2 thì(int) (short) myObject nên hoạt động.

Cách dễ nhất để tìm hiểu là kiểm tra đối tượng trả về và xem xét loại của nó trong trình gỡ lỗi. Ngoài ra, hãy đảm bảo rằng trong hội đồng interop, bạn có giá trị trả về được đánh dấu bằngMarshalAs(UnmanagedType.Struct)


32

Convert.ToInt32 (myobject);

điều này sẽ xử lý trường hợp myobject là null và trả về 0, thay vì ném một ngoại lệ.


Tôi nhận được "Không thể giải quyết biểu tượng 'ToInt'" khi tôi thử nó như thế này. Nó chỉ hoạt động nếu tôi sử dụng ví dụ ToInt32.
Tobias Feil

Chúng ta có thể tìm thấy phương pháp này ở đâu? Có trong Thư viện khung .Net không?
Amir Pourmand Giới thiệu ورمند

8

Sử dụng Int32.TryParsenhư sau.

  int test;
  bool result = Int32.TryParse(value, out test);
  if (result)
  {
     Console.WriteLine("Sucess");         
  }
  else
  {
     if (value == null) value = ""; 
     Console.WriteLine("Failure");
  }

Trên thực tế, Parse gọi TryPude và đưa ra một ngoại lệ nếu TryPude trả về false. Vì vậy, TryPude không xử lý ngoại lệ vì nó không bao giờ ném.
Samuel

Về mặt kỹ thuật, cả hai đều gọi cùng một phương thức NumberToInt32, nhưng chỉ Parse đưa ra các ngoại lệ khi nó không hoạt động.
Samuel

TryPude vẫn yêu cầu chuyển đổi biến thể thành chuỗi. AFAIK vấn đề không chuyển đổi từ một chuỗi thành một int, mà từ một biến thể là một int thành một int thực tế.
Darren Clark

3

Tôi liệt kê sự khác biệt trong mỗi cách đúc. Thật là một loại tay cầm đúc cụ thể và nó không?

    // object to int
    // does not handle null
    // does not handle NAN ("102art54")
    // convert value to integar
    int intObj = (int)obj;

    // handles only null or number
    int? nullableIntObj = (int?)obj; // null
    Nullable<int> nullableIntObj1 = (Nullable<int>)obj; // null

   // best way for casting from object to nullable int
   // handles null 
   // handles other datatypes gives null("sadfsdf") // result null
    int? nullableIntObj2 = obj as int?; 

    // string to int 
    // does not handle null( throws exception)
    // does not string NAN ("102art54") (throws exception)
    // converts string to int ("26236")
    // accepts string value
    int iVal3 = int.Parse("10120"); // throws exception value cannot be null;

    // handles null converts null to 0
    // does not handle NAN ("102art54") (throws exception)
    // converts obj to int ("26236")
    int val4 = Convert.ToInt32("10120"); 

    // handle null converts null to 0
    // handle NAN ("101art54") converts null to 0
    // convert string to int ("26236")
    int number;

    bool result = int.TryParse(value, out number);

    if (result)
    {
        // converted value
    }
    else
    {
        // number o/p = 0
    }


2
var intTried = Convert.ChangeType(myObject, typeof(int)) as int?;

1
Tôi thấy câu trả lời này thực sự hữu ích, tôi đang tìm cách chuyển một byte được đóng hộp vào một int và để nó hoạt động bằng cách sử dụng Convert.ChangeType. Tôi có thể nói có thể không phải là câu trả lời hoàn hảo cho OP, nhưng nó chắc chắn hữu ích với một số người!
Philippe Paré

1

Ngoài ra còn có TryPude .

Từ MSDN:

private static void TryToParse(string value)
   {
      int number;
      bool result = Int32.TryParse(value, out number);
      if (result)
      {
         Console.WriteLine("Converted '{0}' to {1}.", value, number);         
      }
      else
      {
         if (value == null) value = ""; 
         Console.WriteLine("Attempted conversion of '{0}' failed.", value);
      }
   }

1

Lạ, nhưng câu trả lời được chấp nhận có vẻ sai về dàn diễn viên và Chuyển đổi có nghĩa là từ các bài kiểm tra của tôi và đọc tài liệu quá, nó không nên tính đến các toán tử ẩn hoặc tường minh.

Vì vậy, nếu tôi có một biến đối tượng kiểu và lớp "đóng hộp" có một số toán tử ngầm định nghĩa thì chúng sẽ không hoạt động.

Thay vào đó là một cách đơn giản khác, nhưng chi phí hiệu năng thực sự là đúc trước trong động.

(int) (động) myObject.

Bạn có thể thử nó trong cửa sổ Tương tác của VS.

public class Test
{
  public static implicit operator int(Test v)
  {
    return 12;
  }
}

(int)(object)new Test() //this will fail
Convert.ToInt32((object)new Test()) //this will fail
(int)(dynamic)(object)new Test() //this will pass

1
Điều này là đúng , nhưng chắc chắn là điều bạn muốn lập hồ sơ nếu bạn làm việc đó rất nhiều - không phải dynamiclà miễn phí
Marc Gravell

@MarcGravell Tôi hoàn toàn đồng ý với bạn, vì tôi cũng đã viết trong câu trả lời.
eTomm

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.