인터페이스를 사용하여 객체를 한 유형에서 다른 유형으로 변환합니까?

StackOverflow https://stackoverflow.com/questions/303555

문제

동일한 인터페이스를 가진 두 개의 클래스가 있다고 가정합니다.

interface ISomeInterface 
{
    int foo{get; set;}
    int bar{get; set;}
}

class SomeClass : ISomeInterface {}

class SomeOtherClass : ISomeInterface {}

someclass를 나타내는 Isomeinterface 인스턴스가 있다고 가정합니다. 각 멤버를 손으로 복사하지 않고도 새로운 인스턴스로 복사하는 쉬운 방법이 있습니까?

업데이트: 기록을 위해, 나는 ~ 아니다 someclass의 인스턴스를 일부 therthorclass의 인스턴스로 캐스팅하려고합니다. 내가하고 싶은 것은 다음과 같은 것입니다.

ISomeInterface sc = new SomeClass() as ISomeInterface;
SomeOtherClass soc = new SomeOtherClass();

soc.foo = sc.foo;
soc.bar = soc.bar;

이 개체에는 많은 속성이 있기 때문에 각각 손으로 그렇게하고 싶지 않습니다.

도움이 되었습니까?

해결책

"당신은 내가 그렇게 할 수있는 방법에 대한 예를 제시 할 수 있습니까?

Jason, 다음과 같은 것 :

var props = typeof(Foo)
            .GetProperties(BindingFlags.Public | BindingFlags.Instance);

foreach (PropertyInfo p in props)
{
     // p.Name gives name of property
}

런타임에 반사적으로 수행하는 것과는 달리 카피 생성자에 필요한 코드를 뱉어내는 도구를 작성하는 것이 좋습니다.

다른 팁

각 클래스에서 암시 적 연산자를 만들어 전환을 수행 할 수 있습니다.

public class SomeClass
{
    public static implicit operator SomeOtherClass(SomeClass sc)
    {
        //replace with whatever conversion logic is necessary
        return new SomeOtherClass()
        {
            foo = sc.foo,
            bar = sc.bar
        }
    }

    public static implicit operator SomeClass(SomeOtherClass soc)
    {
        return new SomeClass()
        {
            foo = soc.foo,
            bar = soc.bar
        }
    }
    //rest of class here
}

그리고 SomeOtherClass soc = sc; 그리고 그 반대도 마찬가지입니다.

인터페이스의 요점이 그렇게하지 않아도되지 않습니까? 당신은 일부 thorthclass의 구체적인 구현으로 무언가를하고 있습니까? 콘크리트 구현을 사용하는 대신 인터페이스를 사용하면 SomeClass 또는 일부 클래스를 사용하는 경우에는 중요하지 않습니다.

그 외에도, 당신이 할 수있는 최선은 다음과 같은 것처럼 보이는 인터페이스의 각 속성을 복사하는 일종의 도우미 기능 (여전히 수동으로 수행하거나 반사를 살펴 봐야합니다)을 작성하는 것입니다.

   public ISomeInterface CopyValues(ISomeInterface fromSomeClass, ISomeInterface toSomeOtherClass)
   {
    //copy properties here
    return toSomeOtherClass;
    }

그러나 나의 첫 번째 본능은 구현에서 멀리 떨어져 있고 인터페이스를 사용하여 집중하는 것인데, 그 아래에있는 것이 중요하지 않습니다.

반사 ... 모든 속성을 통과하고 다른 개체의 해당 속성에 설정하십시오.

반사 솔루션에 대한 Joe의 답변을 확인하십시오.

나는 당신이 Visual Studio를 사용하고 있다고 가정합니다.

Ctrl+Shift+R 및 Ctrl+Shift+P 바로 가기에 익숙하십니까? 그렇지 않은 경우 Ctrl+Shift+R은 키 스트로크 매크로를 기록/종료합니다. Ctrl+Shift+P는 기록 된 매크로를 재생합니다.

내가 많은 속성을 설정했을 때 내가 한 일은 속성 선언을 설정하기를 원하는 위치에 복사하고 선언을 세트 문으로 변형시키고 커서를 다음 줄로 이동하기위한 매크로를 기록하는 것입니다. 모든 세트 진술이 완료 될 때까지 재생하십시오.

아니요, 객체를 한 유형에서 다른 유형으로 투명하게 변환 (캐스트)하려면, 당신이 가진 객체의 기본 콘크리트 클래스는 동일한 인터페이스를 포함하더라도 캐스팅하려는 클래스에서 상속해야합니다.

그것에 대해 생각해보십시오. 동일한 인터페이스를 구현하기 위해 공통된 두 개체가 모두 메소드 서명의 서브 세트입니다. 그들은 동일한 속성이나 데이터 필드를 가지고 있지 않을 수도 있습니다.

이 일이 작동하지 않습니까?

class MyClass : ICloneable
{
public MyClass()
{

}
public object Clone() // ICloneable implementation
{
MyClass mc = this.MemberwiseClone() as MyClass;

return mc;
}

myclass.clone () 만 호출하면됩니다.

   ISomeInterface sc = new SomeClass() as ISomeInterface;
   SomeOtherClass soc = new SomeOtherClass();
   foreach (PropertyInfo info in typeof(ISomeInterface)
                                     .GetProperties(BindingFlags.Instance
                                                     |BindingFlags.Public))
   {
       info.SetValue(soc,info.GetValue(sc,null),null);
   }

나는 다음을 좋아했고 암시 적 연산자를 사용하여 한 개체에서 다른 개체에서 다른 개체로 변환하는 데 매우 잘 작동합니다.

class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("hello");
            ExecutionReport er = new ExecutionReport("ORDID1234",3000.43,DateTime.UtcNow);
            Order ord = new Order();
            ord = er;
            Console.WriteLine("Transferred values are : " + er.OrderId + "\t" + ord.Amount.ToString() + "\t" + ord.TimeStamp.ToString() + "\t");
            Console.ReadLine();
        }
    }


    public  class Order
    {
        public string OrderId { get; set; }
        public double Amount { get; set; }
        public DateTime TimeStamp { get; set; }
        public static implicit operator ExecutionReport(Order ord)
        {
            return new ExecutionReport()
            {
                OrderId = ord.OrderId,
                Amount = ord.Amount,
                TimeStamp = ord.TimeStamp
            };
        }
        public static implicit operator Order(ExecutionReport er)
        {
            return new Order()
            {
                OrderId = er.OrderId,
                Amount = er.Amount,
                TimeStamp = er.TimeStamp
            };
        }

        public Order()
        { }
    }

    public  class ExecutionReport
    {
        public string OrderId { get; set; }
        public double Amount { get; set; }
        public DateTime TimeStamp { get; set; }
        public ExecutionReport() { }
        public ExecutionReport(string orderId,double amount, DateTime ts)
        {
            OrderId = orderId; Amount = amount; TimeStamp = ts;
        }
    }
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top