인터페이스를 사용하여 객체를 한 유형에서 다른 유형으로 변환합니까?
문제
동일한 인터페이스를 가진 두 개의 클래스가 있다고 가정합니다.
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; } }