익명 형식이 인터페이스를 구현하도록 할 수 있습니까? 내가하고 싶은 코드를 가지고 있는데 어떻게해야할지 모르겠다.
두 가지 대답 중 하나를 선택하지 않았거나 인터페이스를 구현하는 클래스를 만들어 그 인스턴스를 새로 작성합니다. 이것은 실제로 이상적은 아니지만 인터페이스 상단에 얇은 동적 클래스를 만드는 메커니즘이 있는지 궁금합니다. 이렇게하면 인터페이스가 단순 해집니다.
public interface DummyInterface
{
string A { get; }
string B { get; }
}
public class DummySource
{
public string A { get; set; }
public string C { get; set; }
public string D { get; set; }
}
public class Test
{
public void WillThisWork()
{
var source = new DummySource[0];
var values = from value in source
select new
{
A = value.A,
B = value.C + "_" + value.D
};
DoSomethingWithDummyInterface(values);
}
public void DoSomethingWithDummyInterface(IEnumerable<DummyInterface> values)
{
foreach (var value in values)
{
Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
}
}
}
나는 기사를 찾았다.동적 인터페이스 배치그 하나의 접근 방식을 설명합니다. 이것이 최선의 방법인가요?
아니요. 익명 형식은 인터페이스를 구현할 수 없습니다. 로부터C #프로그래밍 가이드:
익명 형식은 하나 이상의 공용 읽기 전용 속성으로 구성되는 클래스 형식입니다. 메소드 나 이벤트와 같은 다른 종류의 클래스 멤버는 허용되지 않습니다. 익명 형식은 object를 제외한 모든 인터페이스 또는 형식으로 캐스팅 할 수 없습니다.
이 질문은 2 년 된 질문 일 수 있지만 스레드의 답변이 모두 사실 일지라도 나는 사실 그것이 사실이라고 말할 수있는 충고에 저항 할 수 없습니다.가능하다익명의 클래스가 인터페이스를 구현하도록하는 것은 비록 약간의 창조적 인 부정 행위가 거기에 도착하기는하지만 말입니다.
2008 년에 나는 그 당시의 고용주를 위해 맞춤 LINQ 제공 업체를 작성하고 있었고 어느 시점에서 다른 익명 사용자로부터 "내"익명 클래스를 말할 수 있어야했습니다. 이는 입력 확인에 사용할 수있는 인터페이스를 구현해야한다는 의미였습니다. 그들. 우리가 해결 한 방법은 (우리가 사용한포스트 샤프)를 사용하여 인터페이스 구현을 IL에 직접 추가 할 수 있습니다. 사실,익명 클래스가 인터페이스를 구현하도록 허용, 규칙을 약간 구부려서 거기에 도착하면됩니다.
익명 형식을 인터페이스에 캐스팅하는 것은 내가 잠시 동안 원했던 것이지만 불행히도 현재 구현에서는 해당 인터페이스를 구현해야합니다.
그 주위의 최상의 솔루션은 구현을 생성하는 동적 프록시의 일부 유형을 갖는 것입니다. 우수한 것을 사용함LinFu 프로젝트너 대체 할 수있어.
select new
{
A = value.A,
B = value.C + "_" + value.D
};
와
select new DynamicObject(new
{
A = value.A,
B = value.C + "_" + value.D
}).CreateDuck<DummyInterface>();
DynamicObject
LinFu 유형?System.Dynamic.DynamicObject
보호 된 생성자 만 있습니다 (.NET 4.5 이상). - jdmcnairDynamicObject
DLR 버전 이전 - Arne Claassen
아니; 익명 형식은 몇 가지 속성을 제외하고는 아무 것도 할 수 없습니다. 자신 만의 유형을 만들어야합니다. 나는 링크 된 기사를 깊이 읽지는 않았지만 Reflection.Emit을 사용하여 새로운 유형을 즉석에서 생성하는 것처럼 보입니다. 그러나 토론을 사물에 한정한다면C #내에서당신은 당신이 원하는 것을 할 수 없습니다.
익명 형식은 동적 프록시를 통해 인터페이스를 구현할 수 있습니다.
나는에 확장 방법을 썼다.GitHub블로그 게시물http://wblo.gs/feE이 시나리오를 지원합니다.
이 메서드는 다음과 같이 사용할 수 있습니다.
class Program
{
static void Main(string[] args)
{
var developer = new { Name = "Jason Bowers" };
PrintDeveloperName(developer.DuckCast<IDeveloper>());
Console.ReadKey();
}
private static void PrintDeveloperName(IDeveloper developer)
{
Console.WriteLine(developer.Name);
}
}
public interface IDeveloper
{
string Name { get; }
}
가장 좋은 해결책은 익명의 클래스를 사용하지 않는 것입니다.
public class Test
{
class DummyInterfaceImplementor : IDummyInterface
{
public string A { get; set; }
public string B { get; set; }
}
public void WillThisWork()
{
var source = new DummySource[0];
var values = from value in source
select new DummyInterfaceImplementor()
{
A = value.A,
B = value.C + "_" + value.D
};
DoSomethingWithDummyInterface(values.Cast<IDummyInterface>());
}
public void DoSomethingWithDummyInterface(IEnumerable<IDummyInterface> values)
{
foreach (var value in values)
{
Console.WriteLine("A = '{0}', B = '{1}'", value.A, value.B);
}
}
}
쿼리의 결과를 인터페이스 유형으로 변환해야합니다. 더 좋은 방법이있을 수도 있지만 찾을 수는 없습니다.
values.OfType<IDummyInterface>()
던지기 대신에. 이 컬렉션은 실제로 해당 유형으로 캐스팅 할 수있는 객체 만 반환합니다. 그것은 모두 당신이 원하는 것에 달려 있습니다. - Kristoffer L
구체적으로 묻는 질문에 대한 대답은 아니오입니다. 그러나 조롱 한 프레임 워크를 보셨습니까? MOQ를 사용하지만 거기에는 수백만 가지가 있으며 인라인으로 / 스텁 (부분적으로 또는 완전히) 인터페이스를 구현할 수 있습니다. 예 :
public void ThisWillWork()
{
var source = new DummySource[0];
var mock = new Mock<DummyInterface>();
mock.SetupProperty(m => m.A, source.Select(s => s.A));
mock.SetupProperty(m => m.B, source.Select(s => s.C + "_" + s.D));
DoSomethingWithDummyInterface(mock.Object);
}