Object를 실제 유형으로 캐스팅하는 방법은 무엇입니까?


121

만약 내가 가지고 있다면:

void MyMethod(Object obj) {   ...   }

obj실제 유형이 무엇인지 어떻게 캐스트 할 수 있습니까?


2
컴파일 타임에 유형이 알려져 있습니까?
— psubsee2003

1
그리고 이것으로부터 무엇을 성취하기를 기대합니까? 달성하고자하는 방식보다는 달성하고자하는 것이 무엇인지 알려주십시오.
— Jon Skeet

@JonSkeet : 객체에서 함수를 호출 할 수 있기를 원합니다. obj.MyFunction();실제 개체에 해당 기능이 있음을 알고 있지만 현재 는 컴파일되지 않습니다.
— Paul Lassiter 2012 년

@ psubsee2003 : 그렇지 않습니다. interop을 통해 전달되는 개체 참조이기 때문입니다.
— Paul Lassiter 2012 년

3
@PaulLassiter : 유형을 모르는 경우 MyFunction메서드를 선언하는 것은 무엇 입니까?
— Jon Skeet

답변:


194

실제 유형을 알고 있다면 다음을 수행하십시오.

SomeType typed = (SomeType)obj;
typed.MyFunction();

실제 유형을 모르면 실제로는 아닙니다. 대신 다음 중 하나를 사용해야합니다.

  • 반사
  • 잘 알려진 인터페이스 구현
  • 동적

예를 들면 :

// reflection
obj.GetType().GetMethod("MyFunction").Invoke(obj, null);

// interface
IFoo foo = (IFoo)obj; // where SomeType : IFoo and IFoo declares MyFunction
foo.MyFunction();

// dynamic
dynamic d = obj;
d.MyFunction();

1
Swift에서 동등한 구문은 무엇입니까?
— Nagendra Rao

1
신경 쓰지 마십시오 . 유형 as캐스팅 및 type(of: ClassName)인스턴스 유형을 확인하는 기능이 있습니다.
— Nagendra Rao

43

나는 당신이 할 수 있다고 생각하지 않는다.

void MyMethod(Object obj, Type t)
{
    var convertedObject = Convert.ChangeType(obj, t);
    ...
}

UPD :

이것은 당신을 위해 일할 수 있습니다.

void MyMethod(Object obj)
{
    if (obj is A)
    {
        A a = obj as A;
        ...
    } 
    else if (obj is B)
    {
        B b = obj as B;
        ...
    }
}

4
이것은 정말로 쓸모없는 대답이며, 투표 할 자격이 없습니다. 객체 유형의 객체를 반영하면 OP에서 요청한대로 객체의 "실제 유형"이 생성되지 않습니다. 또한 MyMethod 로직은 obj가 A 유형일 수 있고 B 유형일 수도 있기 때문에 결함이 있습니다. 로직은 "실제 유형"(OP 요청에 따라)을 제공하지 않습니다. 호환 가능한 유형을 제공하지만 반드시 그런 것은 아닙니다. 거기에 원하는 유형.
— Jazimov

obj.GetType ()을 사용하십시오. 확실히 실제 유형을 반환합니다.
— JSON

3

JsonConvert.DeserializeObject (object.ToString ());


이것은 만족스러운 대답이 아닙니다. OP의 질문은 Json 또는 직렬화와 관련이 없습니다.

@ user12637955 이것은 실제로 작동하는 대답이지만 boxing 및 unboxing, 즉 object-> ToString ()-> 구체적인 유형으로 인해 더 복잡합니다. 더 정확하게하려면 다음과 같이 표시되어야합니다.var myType = JsonConvert.DeserializeObject<MyType>(object.ToString());
— Coke

1

제 경우에는 AutoMapper가 잘 작동합니다.

AutoMapper는 명시적인 구성없이 동적 개체와 매핑 할 수 있습니다.

public class Foo {
    public int Bar { get; set; }
    public int Baz { get; set; }
}
dynamic foo = new MyDynamicObject();
foo.Bar = 5;
foo.Baz = 6;

Mapper.Initialize(cfg => {});

var result = Mapper.Map<Foo>(foo);
result.Bar.ShouldEqual(5);
result.Baz.ShouldEqual(6);

dynamic foo2 = Mapper.Map<MyDynamicObject>(result);
foo2.Bar.ShouldEqual(5);
foo2.Baz.ShouldEqual(6);

마찬가지로 사전에서 객체로 직접 매핑 할 수 있으며 AutoMapper는 속성 이름과 함께 키를 정렬합니다.

더 많은 정보 https://github.com/AutoMapper/AutoMapper/wiki/Dynamic-and-ExpandoObject-Mapping


1

이 방법은 가장 효율적이지는 않지만 간단하고 작업을 수행합니다.

두 가지 작업을 수행합니다. 먼저 기본적으로 직렬화 인 .ToString ()을 호출 한 다음 Newtonsoft 너겟 ( 설치해야 함) 을 사용한 역 직렬화를 호출 합니다 .

public T Format<T>(Object obj) =>
    JsonConvert.DeserializeObject<T>(obj.ToString());

당신은 미래의 독자들을 위해 당신의 대답을 간략하게 설명해야합니다.
— Suraj Kumar

0

귀하의 경우 MyFunction()방법은 하나 개의 클래스 (와 그 하위) 만 정의, 시도

void MyMethod(Object obj) 
{
    var o = obj as MyClass;
    if (o != null)
        o.MyFunction();
}

호출하려는 함수를 정의하는 관련없는 클래스에 많은 수가있는 경우 인터페이스를 정의하고 클래스가 해당 인터페이스를 정의하도록해야합니다.

interface IMyInterface
{
    void MyFunction();
}

void MyMethod(Object obj) 
{
    var o = obj as IMyInterface;
    if (o != null)
        o.MyFunction();
}

0

예를 들어 이제 유형이 abc라는 클래스에서 지향되는 경우 실제 유형으로 캐스팅하십시오. 다음과 같이 함수를 호출 할 수 있습니다.

(abc)(obj)).MyFunction();

기능을 모르는 경우 다른 방식으로 수행 할 수 있습니다. 항상 쉽지는 않습니다. 그러나 서명으로 어떤 식 으로든 찾을 수 있습니다. 이것이 귀하의 경우라면 저희에게 알려 주셔야합니다.


-1

실제 유형으로 변환하는 것은 쉽습니다.

void MyMethod(Object obj) {
    ActualType actualyType = (ActualType)obj;
}

8
이것은 비논리적입니다. 실제로 실제 유형을 모릅니다. 어떻게해야합니까?
— Allen Linatoc 2015 년

-2
Implement an interface to call your function in your method
interface IMyInterface
{
 void MyinterfaceMethod();
}

IMyInterface MyObj = obj as IMyInterface;
if ( MyObj != null)
{
MyMethod(IMyInterface MyObj );
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.