2010-04-29 4 views
10

은 쉽게 을 장식 할 수 있습니까?동적으로 오브젝트를 장식하는 C#

예를 들어 내가 List<PointF>이라고 가정 해 보겠습니다. 이 목록은 실제로 사인 함수의 플롯입니다. 나는이 포인트들을 살펴보고 피크인지 여부에 상관없이 각 PointF에 플래그를 추가하고 싶습니다.

하지만 부울 속성이있는 새 확장 된 SpecialPointF 또는 기타를 만들고 싶지 않습니다.

게으른 나를 당신이 원하는 모든 것을 판단하지만, 게으름은 (또한 나쁜 아이디어)

편집 태어난 방법 멋진 아이디어입니다 : 나는 권투 솔루션뿐만 아니라 당신이 가지고 올 수있는 흥미로운 해킹을 받아 들일 수 있습니다. 나를 파생시키는 것을 정말로 멈추게하는 것은 아무것도 없습니다. 더 재미있는 방법이 있는지 알고 싶습니다.

+1

방금 ​​폐결 문장에 +1을주었습니다. 그래도 질문에 대한 대답은 확실하지 않습니다. –

답변

4

포인트 당 계산할 수있는 방법이 있다면 플래그를 추가 할 필요가 없으며이를 확장하지 않고 extension 메서드를 사용할 수 있습니다.

Some like with PointF.isPeak();

그것은 같은 작동합니다

public static class Extensions 
{ 
    public static bool isPeak (this PointF p) 
    { 
     do crazy math... 

     return result; 
    } 
} 

봐라을, 당신은 당신의 PointF 클래스에 계산을해야합니다.

그런데 public static 클래스는 가장 바깥 쪽 범위에 있어야하며 중첩 할 수 없습니다.그것은 할 수 있습니다

+1

+1이 아니라'new WrapperClass {...'라고 말하면됩니다. 훌륭한 제안이지만, isPeak는 .Net 명명 규칙 (첫 번째 문자는 대문자이어야합니다)과 일치하지 않습니다. –

+0

그것은 환상적인 아이디어입니다. 나는 그것을 좋아한다. –

+0

@Francisco : 확장 방법은 좋은 생각입니다. 그러나이 경우 포함되지 않은 시리즈의 피크를 포인트가 어떻게 알 수 있습니까? 포인트에 시리즈의 포인터가 포함되어 있지 않다면, 그 포인터의 일부입니다. –

5

아니요, 당신이 원하는 것을 (구체적으로) 할 방법이 없습니다.

C# 3.0 이상을 사용한다고 가정 할 때 익명 형식을 사용하여 함수 외부에 정보를 노출하지 않으려는 경우이를 수행 할 수 있습니다.

var decoratedList = sourceList.Select(pt => new 
        { 
         IsPeak = GetIsPeak(pt), 
         Point = pt 
        }).ToList(); 

이렇게하면 List<T> 개체가 새로 추가됩니다. 단일 함수 호출 외부로 확장 할 수 없으며 기존 함수를 수정하는 대신 목록을 작성하기 때문에 문제가 해결되지 않을 수 있습니다. 그러나이 방법이 도움이되기를 바랍니다.

+0

멋진 아이디어입니다. 아직 익명 유형을 사용하지 않았으므로 생각조차하지 않았습니다. 우리는 최신 C#을 사용하여 매우 멋지다. 그래서 문제는 아니다. –

+0

@Oren : 멋지지만 가장 큰 경고는 기능 밖에서 노출 될 수 없다는 것입니다. 그렇게해야한다면 비슷한 서명으로 간단한 래퍼 클래스를 만든 다음'new {... ' –

2

아니요. 불가능합니다. 가장 가까운

그냥

var decorationData = new Dictionary <Object, bool> 

을 만든 다음 거기에 당신의 가치를 저장하는 것입니다. 유형을 직접 확장 할 필요가 없습니다. 확장 메서드를 사용하여 저장된 데이터에 액세스 할 수도 있습니다. 저장된 데이터는 개체의 직접적인 속성 인 것처럼 보입니다.

public static class PointFPeakExtensions 
{ 
    private static var decorationData = new Dictionary <PointF, bool> 

    public static bool IsPeak (this PointF point) 
    { 
     return decorationData[point]; 
    } 
    public static void SetPeak (this PointF point, bool isPeak) 
    { 
     decorationData[point] = isPeak; 
    } 
} 

그리고 당신의 편집에 추가 : 당신은 또한 단지 장식 데이터와 같은 nullable 형식이 클래스 라이브러리에서 구현되는 같은 방식으로 참조 유형 (포함 제네릭 형식으로이 문제를 해결할 수

). 그러나 여전히 유형을 사용하는 장소에서 서명을 변경해야한다는 것을 의미합니다 (데코레이터를 찾고있을 때 원하지 않는 것일 수 있음).

3

새로운 dynamic 키워드를 사용하여이 작업을 수행하고 ExpandoObject는 C# 4.0의 구성,하지만 난 아직 그것으로 직접 경험을하지 않습니다. 내가 쉽게이 정확한 문제를 해결하기 위해 만들어졌습니다 이해, 그래서 당신은

dynamic something = new ExpandoObject(); 
something.Anything = "whatever you want"; 

내가 그것을 동적 유형을 기존 확장 할 수 믿을 말할 수 있지만,이 패배하는 새로운 서브 클래스를 생성해야 할 수 있습니다로 운동의 모든 목적.

거의 동일한 솔루션을 확장 메서드를 사용하여 만들 수 있습니다. ExpandoObject은 내부적으로 Dictionary으로 구현되었지만 고급 기본 구문을 추가합니다.

class Program { 

    static void Main(string[] args) 
    { 
     PointF p = new PointF(0, 0); 

     p.SetFlag(true); 

     if (p.GetFlag()) 
     Console.WriteLine("win"); 
    } 

} 

public static class Extensions 
{ 
    private static Dictionary<PointF, bool> flags = new Dictionary<PointF, bool>(); 
    public static bool GetFlag(this PointF key) 
    { 
     return flags[key]; 
     //OR return flags.ContainsKey(key) ? flags[key] : false; 
    } 

    public static void SetFlag(this PointF key, bool val) 
    { 
     flags[key] = val; 
    } 
} 
+0

대신 p.SetFlag를 사용하면 Extensions.SetFlag (p, true)를 호출 할 수 있습니까? ? –

+0

아니요, 확장 방법을 사용하면 "기본"으로 보이는 통화를 할 수 있습니다. 자동으로'Extensions.SetFlag (p, true)'를 자동으로 호출합니다. –

관련 문제