[c#] 명시 적 형변환을 사용하여 파생 클래스 참조에 기본 클래스 개체를 할당 할 수 있습니까?

C #에서 명시 적 형식 변환을 사용하여 파생 클래스 참조에 기본 클래스 개체를 할당 할 수 있습니까?

나는 그것을 시도했고 런타임 오류가 발생합니다.



답변

아니요. 파생 클래스에 대한 참조는 실제로 파생 클래스의 인스턴스 (또는 null)를 참조해야합니다. 그렇지 않으면 어떻게 작동 할 것으로 예상합니까?

예를 들면 :

object o = new object();
string s = (string) o;
int i = s.Length; // What can this sensibly do?

기본 형식의 인스턴스를 파생 형식으로 변환하려면 적절한 파생 형식 인스턴스를 만드는 메서드를 작성하는 것이 좋습니다. 또는 상속 트리를 다시보고 처음부터이 작업을 수행 할 필요가 없도록 재 설계를 시도하십시오.


답변

아니요, 파생 클래스 참조에 할당하는 것은 “기본 클래스는 파생 클래스를 완전히 대체 할 수 있습니다. 파생 클래스가 할 수있는 모든 작업을 수행 할 수 있습니다.”라고 말하는 것과 같기 때문에 불가능합니다. 이는 일반적으로 파생 클래스가 제공하므로 사실이 아닙니다. 기본 클래스보다 더 많은 기능을 제공합니다 (적어도 상속의 개념입니다).

기본 클래스 개체를 매개 변수로 사용하여 값을 복사하는 파생 클래스에 생성자를 작성할 수 있습니다.

이 같은:

public class Base {
    public int Data;

    public void DoStuff() {
        // Do stuff with data
    }
}

public class Derived : Base {
    public int OtherData;

    public Derived(Base b) {
        this.Data = b.Data;
        OtherData = 0; // default value
    }

    public void DoOtherStuff() {
        // Do some other stuff
    }
}

이 경우 기본 개체를 복사하고 파생 멤버에 대한 기본값이있는 완전한 기능의 파생 클래스 개체를 가져옵니다. 이렇게하면 Jon Skeet이 지적한 문제를 피할 수도 있습니다.

Base b = new Base();//base class
Derived d = new Derived();//derived class

b.DoStuff();    // OK
d.DoStuff();    // Also OK
b.DoOtherStuff();    // Won't work!
d.DoOtherStuff();    // OK

d = new Derived(b);  // Copy construct a Derived with values of b
d.DoOtherStuff();    // Now works!


답변

이 문제가 발생하여 유형 매개 변수를 사용하고 현재 개체를 해당 유형으로 변환하는 메서드를 추가하여 해결했습니다.

public TA As<TA>() where TA : Base
{
    var type = typeof (TA);
    var instance = Activator.CreateInstance(type);

     PropertyInfo[] properties = type.GetProperties();
     foreach (var property in properties)
     {
         property.SetValue(instance, property.GetValue(this, null), null);
     }

     return (TA)instance;
}

즉, 다음과 같이 코드에서 사용할 수 있습니다.

var base = new Base();
base.Data = 1;
var derived = base.As<Derived>();
Console.Write(derived.Data); // Would output 1


답변

다른 많은 사람들이 대답했듯이 아니요.

기본 형식을 파생 형식으로 사용해야하는 경우에 다음 코드를 사용합니다. 예, 그것은 Liskov Substitution Principle (LSP)에 위배되며, 그렇습니다. 우리는 대부분 상속보다 구성을 선호합니다. Markus Knappen Johansson의 원래 답변을 기반으로 한 소품입니다.

기본 클래스의이 코드 :

    public T As<T>()
    {
        var type = typeof(T);
        var instance = Activator.CreateInstance(type);

        if (type.BaseType != null)
        {
            var properties = type.BaseType.GetProperties();
            foreach (var property in properties)
                if (property.CanWrite)
                    property.SetValue(instance, property.GetValue(this, null), null);
        }

        return (T) instance;
    }

허용 :

    derivedObject = baseObect.As<derivedType>()

반사를 사용하기 때문에 “비싸다”. 그에 따라 사용하십시오.


답변

불가능하므로 런타임 오류가 발생합니다.

그러나 파생 클래스의 인스턴스를 기본 클래스 유형의 변수에 할당 할 수 있습니다.


답변

JsonConvert를 사용한 솔루션 (타입 캐스트 대신)

오늘은 동일한 문제에 직면하고 난 간단하고 발견 문제에 대한 빠른 솔루션을 사용 JsonConvert.

var base = new BaseClass();
var json = JsonConvert.SerializeObject(base);
DerivedClass derived = JsonConvert.DeserializeObject<DerivedClass>(json);


답변

여기 모두가 말했듯이, 그것은 직접적으로 가능하지 않습니다.

내가 선호하고 다소 깨끗한 방법은 AutoMapper 와 같은 Object Mapper를 사용하는 것 입니다 .

한 인스턴스에서 다른 인스턴스 (동일한 유형일 필요는 없음)로 속성을 자동으로 복사하는 작업을 수행합니다.