2011-03-06 5 views
4

사용할 수있는 클래스에 대한 기본값을 제공 할 수 있지만 문제가 변경되면 해당 클래스에 대한 모든 참조가 적용되고 "기본값"이되지 않습니다. 이 값과 같은 기본값을 사용하면 메모리에 저장되며 기본값을 사용하는 모든 참조로 전달할 수 있습니다.정적 불변 기본 인스턴스

간단한 예는

class A 
{ 
    static public A Default; 
} 

는 그런 일이 다시 A의 "기본"인스턴스로 A.Default를 사용할 수있는 문제는 불변 또는 적어도 "동결"과 변화에되지 않는 것입니다 그것은 모든 참조를 바꿀 것입니다. 우연히 기본값이 변경되면 혼란을 야기 할 수있는 행동이라면 좋을 수 있습니다.

정말 필요한 것은 기본값을 고정하고 고정 해제하는 방법입니다.

분명히 한 가지 방법은 모든 설정 도구를 조건에서만 설정하고 컬렉션을 읽기 전용으로 표시하는 것입니다. 이런 간단한 행동을 제공하는 것은 반복적 인 일처럼 보입니다.

간단한 라이브러리, 패턴 또는 리플렉션이 있습니까? Copy-on-write 능력은 Default가 변경하려고 시도 할 때 새로운 변경 가능한 인스턴스가 생성 될 수 있다는 점에서 좋을 것입니다. 뿐만 아니라 성능을 향상시킬 수있는 기회가 있다면 플라이급 인스턴스도 만들 수 있습니다 (변경 규모).

예 처음에 동일한 상태로 모두 1M 크기의 (메모리 크기) 객체를 생성한다고 가정합니다. 기본 패턴을 사용하면 실제 객체가 하나만 생성됩니다. 모든 상태 (위치)에 대해 1 개의 매개 변수를 변경한다고 가정하지만 객체 자체는 매우 큽니다. 플라이 웨이트 패턴을 사용하면 1M의 새 오브젝트 대신 (더 느리지 만 평소와 같이 적은 메모리 만) 추적 할 수 있도록 1M 변경된 매개 변수를 갖게됩니다. 충분한 매개 변수가 변경된 후에는 전체 블로운 오브젝트가 마침내 참조로 지정됩니다.

뭐니 뭐니해도?

+1

어떤 상태에서 기본값을 "고정 해제"하고 기본값을 "고정 해제 할 수 있습니까?" – shahkalpesh

+0

실제로이 복합체가 필요한 것이 확실합니까? –

+0

이것은 디자인 상 결함 인 것 같습니다. "Default"인스턴스가 아직 변경되지 않았을 때 둘 다 변경할 수없는 클래스 A가 있습니다.Perhapes 당신은 두 개의 클래스를 필요로하는 불변하고 가변적 인 클래스 또는 클래스를 사용합니다. A는 실제로 구조체 또는 객체와 같은 값 유형이어야합니다 (예 : String과 같은) – MerickOWA

답변

0

사용할 수있는 상자와 비슷한 것은 없습니다. 자신 만의 copy-on-write 인스턴스와 코드를 만들어야합니다.

  • 작은 "참조"개체를 만들고 때마다 누군가가 "Default"속성은 그것의 새로운 인스턴스를 돌려 읽

    상황이 실제 복사 (copy-on-write) 동작을 위해 할 수 있습니다. 이 개체는 항상 동일한 (개인, 읽기 전용) 내부 데이터를 참조합니다.

  • 데이터가 변경 되어도 읽기 전용 데이터가 계속 될 때마다 내부 데이터 복사본을 만들어 참조 개체에 할당하십시오.

.NET Framework 디자이너는 유사한 요구 사항을 가진 일부 클래스에 대해보다 명확한 경로를 사용했습니다. 예를 들어 CultureInfo을 보면 "기본"인스턴스가 읽기 전용이고 해당 인스턴스를 수정하려고하면 예외가 발생합니다. 그러나 쉽게 변경할 수있는 복사본을 만들 수 있습니다 (생성자 중 하나에서 다른 CultureInfo 인스턴스를 허용 함).

+0

그래,하지만 그런 일을 일반적으로 효율적으로 수행하는 방법을 모르겠습니다. 그것은 한 가지 경우에 그것을하는 것은 어렵지 않지만 당신이 항상 그것을해야한다면 혼란입니다. 그들의 읽기 전용 기본값을 어떻게 구현 했습니까? 도움을 보면 그들은 래퍼를 사용했지만이 래퍼는 먼 길을 마쳤습니까? – AbstractDissonance

+0

항상 그렇게해야한다면 디자인이 어떻게 든 잘못 될 수 있습니다. MS와'CultureInfo'와 관련해서, 내가 말할 수있는 것부터 그들은 명시 적으로 래퍼를 구현했다고 말할 수 있습니다. 어쨌든 항상 템플릿을 사용하여 상용구 코드를 생성하는 코드 생성 도구를 사용할 수 있으므로 기본적으로 템플릿을 한 번만 작성한 다음 코드를 생성해야합니다. 또는 추상적 인 클래스 나 인터페이스를 사용하고 런타임에'Reflection.Emit'을 사용하여 코드를 생성 할 수 있습니다. 많은 가능성이 있습니다. – Lucero

0

이 마음에 봄을 할 수있는 몇 가지 방법이 있습니다 :

  1. 가지고 IsReadOnly라는 플래그, 귀하의 뮤 테이터 (인스턴스를 변경할 수 있습니다 세터 및 방법)의 모든 경우에 예외를 발생하도록 그건 사실이야. Default 인스턴스가 IsReadOnly이 true로 설정된 상태에서 생성됩니다.

  2. 모든 뮤 테이타가 예외를 throw하는 기본 클래스 (FooReadOnly)를 만든 다음 뮤 테이터가 작동하는 파생 클래스 (Foo)를 만듭니다. Default 인스턴스의 유형은 FooReadOnly입니다. 당신은 WPF/실버 라이트에서 어떻게 DependancyObject (들) 및 DependanceProperty (들) 직장에서 보일 수 있습니다

0

. 여기

는 5

class A : DependancyObject { 
    static DependancyProperty PropertyFoo = DependanceProperty.Register("Foo", typeof(int), typeof(A), new PropertyMetadata(5)); 

    int Foo { 
    get { return (int)GetValue(PropertyFoo); } 
    set { SetValue(PropertyFoo, value); } 
    } 

는 "수동에 가지고있는 단점의 기본값 속성"푸 "와 함께 클래스"A "에 대한 WPF/실버 라이트에서 작동하는 방법의 예 "속성을 구현하면 간단한"int Foo {get; set;} "구문을 활용할 수 없지만 코드 조각은 상당히 도움이 될 수 있습니다.

분명히 WPF 또는 Silverlight를 사용하고 싶지 않은 경우이 모든 것을 직접 구현해야하지만 다음과 같은 이점이 있습니다.

DependancyProperties는 개체이므로 값을 덮어 쓰지 않은 모든 DependancyObject에서 공유 할 수있는 기본값을 보유 할 수 있습니다.

DependancyObjects는 값이 변경된 경우에만 값 목록을 유지하므로 기본값과 동일한 개체는 추가 메모리를 사용하지 않습니다.

모든 속성 집합은 DependancyObject.SetValue를 통과하기 때문에 특정 속성이나 전체 개체를 읽기 전용으로 만들기위한 한 곳의 논리에서 쉽게 구현할 수 있습니다.

속성 등의 애니메이션과 같이 추가 할 수있는 다른 장점이나 기능이 있지만 구현 한 경우 원하는대로 간단하게/복잡하게 유지할 수 있습니다.

interface ISomeClass 
{ 
    string MyProperty { get; } 
} 

class SomeClass : ISomeClass 
{ 
    string MyProperty { get; set; } 

    public static ISomeClass Default = new SomeClass(); 
} 

그런 다음 적용 할 수 있습니다 기본에 언제든지 변경이 필요한 것으로, 변경 가능한

:

2

하나는 내가 사용 가능한 방법은 읽기 전용 인터페이스를 구현하고 것과 정적 기본 반환 유형을 변경하는 것입니다 아마도 별도의 방법으로, 가 명시 적으로 요청 참조 :

 public static SomeClass GetMutableDefault() 
     { 
      return Default as SomeClass; 
     } 

그런 다음 컴파일 시간이 명시 적으로 말한다 않는 한 SomeClass 인스턴스를 변경하려고 시도하는 모든 방법은 기본값을 사용하지 않는 것을 확인를 얻을.

관련 문제