상속된 구성원 숨기기
상속받은 멤버들을 효과적으로 숨길 방법을 찾고 있습니다.저는 공통 기본 클래스에서 상속되는 클래스 라이브러리를 가지고 있습니다.최신 하위 클래스 중 일부는 종속성 속성을 상속합니다. 종속성 속성은 오래되어 IntelliSense를 사용하거나 비주얼 디자이너에서 클래스를 사용할 때 약간 혼란스러울 수 있습니다.
이러한 클래스는 모두 WPF 또는 Silverlight 2.0용으로 컴파일되도록 작성된 컨트롤입니다.에 대해 알고 있습니다.ICustomTypeDescriptor
그리고.ICustomPropertyProvider
하지만 실버라이트에서는 사용할 수 없을 거라 확신합니다.
기능적인 문제라기보다는 사용성 문제입니다.어떻게 해야 하나?
갱신하다
가 정말 중 는 제 로부터 온 제가에, ▁the▁▁with▁i▁some▁member▁thatties▁tool▁proper▁for▁come▁i▁because▁ancestors'▁from없수▁specific숨▁oft▁of▁do▁a▁can멤제니가▁own▁the습▁my▁like다길를버▁hide▁and,▁are▁i▁really▁to▁not저는'▁would▁designingmnew
교환입니다.(알아요, 말도 안 돼요)
위의 Michael이 제안하는 것처럼 재정의하고 사람들이 재정의된(sp?) 메서드를 사용하지 못하도록 하려면 해당 메서드를 사용하지 않는 것으로 표시합니다.
[Obsolete("These are not supported in this class.", true)]
public override void dontcallmeanymore()
{
}
두 번째 parm이 true로 설정된 경우, 누군가가 해당 메서드를 호출하려고 하면 컴파일러 오류가 생성되고 첫 번째 parm의 문자열이 메시지가 됩니다.parm2가 false이면 컴파일러 경고만 생성됩니다.
내가 알기로는 상속된 구성원의 사용을 방지할 수 없지만 EditorBrowsableAttribute를 사용하여 IntelliSense에서 해당 구성원을 숨길 수 있습니다.
Using System.ComponentModel;
[EditorBrowsable(EditorBrowsableState.Never)]
private string MyHiddenString = "Muahahahahahahahaha";
편집: 문서 주석에서 이것을 보았는데, 이것은 이 목적에 약간 쓸모가 없게 만듭니다.
이 특성이 "같은 어셈블리의 클래스에서 구성원을 억제하지 않음"을 나타내는 중요한 참고 사항이 있습니다.그것은 사실이지만 완전하지는 않습니다.실제로 속성은 동일한 솔루션의 클래스에서 구성원을 억제하지 않습니다.
가능한 한 가지 방법은 다른 클래스에서 확장하는 것이 아니라 개체를 포함하는 것입니다.이렇게 하면 노출할 대상을 노출하는 데 있어 가장 유연한 방법이 제공되지만, 해당 유형의 개체가 꼭 필요한 경우에는 이상적인 솔루션이 아닙니다(그러나 개체를 처음부터 노출할 수도 있음).
따라서:
public class MyClass : BaseClass
{
// Your stuff here
}
다음이 됩니다.
public class MyClass
{
private BaseClass baseClass;
public void ExposeThisMethod()
{
baseClass.ExposeThisMethod();
}
}
또는:
public class MyClass
{
private BaseClass baseClass;
public BaseClass BaseClass
{
get
{
return baseClass;
}
}
}
저는 당신이 가장 최소한의 해킹 방법은 상속이 아닌 구성을 고려하는 것이라고 생각합니다.
또는 원하는 구성원이 있는 인터페이스를 만들고, 파생된 클래스가 해당 인터페이스를 구현하고, 인터페이스를 기반으로 프로그래밍할 수 있습니다.
이것에 지금은 꽤 , 위한 가장 방법은 을 이에대몇한있알며,현오었지만되를,위가간다같선다것니입으로 입니다.new private
.
제가 현재 연구하고 있는 예를 생각해 보십시오. 여기에는 타사 DLL의 모든 방법을 사용할 수 있는 API가 있습니다.나는 그들의 방법을 취해야 하지만, 나는 a를 사용하고 싶습니다."getThisValue" 및 "setThisValue" 메서드 대신 Net 속성을 사용합니다.그래서 저는 두 번째 클래스를 만들고 첫 번째 클래스를 상속하고 get 및 set 메서드를 사용하는 속성을 만든 다음 원래 get 및 set 메서드를 비공개로 재정의합니다.그것들은 여전히 그것들 위에 뭔가 다른 것을 만들고자 하는 사람들이 이용할 수 있습니다. 하지만 그들이 단지 제가 만들고 있는 엔진을 사용하기를 원한다면, 그들은 방법 대신에 속성을 사용할 수 있을 것입니다.
이중 클래스 방법을 사용하면 사용할 수 없는 것에 대한 제한이 없어집니다.new
회원들을 숨기겠다는 선언사용할 수 없습니다.override
구성원이 가상으로 표시된 경우.
public class APIClass
{
private static const string DllName = "external.dll";
[DllImport(DllName)]
public extern unsafe uint external_setSomething(int x, uint y);
[DllImport(DllName)]
public extern unsafe uint external_getSomething(int x, uint* y);
public enum valueEnum
{
On = 0x01000000;
Off = 0x00000000;
OnWithOptions = 0x01010000;
OffWithOptions = 0x00010000;
}
}
public class APIUsageClass : APIClass
{
public int Identifier;
private APIClass m_internalInstance = new APIClass();
public valueEnum Something
{
get
{
unsafe
{
valueEnum y;
fixed (valueEnum* yPtr = &y)
{
m_internalInstance.external_getSomething(Identifier, yPtr);
}
return y;
}
}
set
{
m_internalInstance.external_setSomething(Identifier, value);
}
}
new private uint external_setSomething(int x, float y) { return 0; }
new private unsafe uint external_getSomething(int x, float* y) { return 0; }
}
이제 valueEnum을 두 클래스 모두에서 사용할 수 있지만 APIUsageClass 클래스에는 속성만 표시됩니다.API 클래스는 기존 API를 확장하거나 다른 방식으로 사용하려는 사용자를 위해 계속 사용할 수 있으며 API Usage 클래스는 보다 단순한 것을 원하는 사용자를 위해 사용할 수 있습니다.
궁극적으로 제가 할 일은 APIC 클래스를 내부로 만들고 상속받은 클래스만 노출하는 것입니다.
대부분의 독자들이 기대하는 지능을 포함하여 완전히 숨기고 사용하지 않도록 표시하는 것.
[Obsolete("Not applicable in this class.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
저는 제안된 솔루션을 모두 테스트했고 그들은 실제로 새로운 멤버를 숨기지 않습니다.
하지만 이 방법은 다음과 같습니다.
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{
get { return _myHiddenProperty; }
}
그러나 코드 뒤에서는 여전히 액세스할 수 있으므로 사용되지 않는 속성을 추가합니다.
[Obsolete("This property is not supported in this class", true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
public new string MyHiddenProperty
{
get { return _myHiddenProperty; }
}
위에서 C#에서는 상속받은 방법과 속성에 대한 접근 수식어를 변경할 수 없다고 분명히 언급했지만, 저는 암묵적인 캐스팅을 이용한 일종의 '가짜 상속'을 통해 이 문제를 극복했습니다.
예:
public class A
{
int var1;
int var2;
public A(int var1, int var2)
{
this.var1 = var1;
this.var2 = var2;
}
public void Method1(int i)
{
var1 = i;
}
public int Method2()
{
return var1+var2;
}
}
이제 당신이 원하는 것은class B
에서물은에서 class A
일부 하거나 Method1을 .
public class B
{
private A parent;
public B(int var1, int var2)
{
parent = new A(var1, var2);
}
int var1
{
get {return this.parent.var1;}
}
int var2
{
get {return this.parent.var2;}
set {this.parent.var2 = value;}
}
public Method1(int i)
{
this.parent.Method1(i*i);
}
private Method2()
{
this.parent.Method2();
}
public static implicit operator A(B b)
{
return b.parent;
}
}
마지막에 암묵적인 캐스팅을 포함시킴으로써, 우리가 치료할 수 있게 해줍니다.B
로서의 목적.A
우리가 필요할 때.암시적 캐스트를 정의하는 것도 유용할 수 있습니다.A->B
.
이 접근 방식의 가장 큰 결함은 "상속"하려는 모든 메서드/속성을 다시 작성해야 한다는 것입니다.이 접근법에는 아마도 더 많은 결함이 있겠지만, 저는 그것을 일종의 "가짜 상속"으로 사용하는 것을 좋아합니다.
참고:
이를 통해 액세스 가능성을 변경할 수 있습니다.public
속성, 그것은 만드는 문제를 해결하지 못합니다.protected
공공 재산
인터페이스를 사용할 수 있습니다.
public static void Main()
{
NoRemoveList<string> testList = ListFactory<string>.NewList();
testList.Add(" this is ok ");
// not ok
//testList.RemoveAt(0);
}
public interface NoRemoveList<T>
{
T this[int index] { get; }
int Count { get; }
void Add(T item);
}
public class ListFactory<T>
{
private class HiddenList: List<T>, NoRemoveList<T>
{
// no access outside
}
public static NoRemoveList<T> NewList()
{
return new HiddenList();
}
}
언급URL : https://stackoverflow.com/questions/1528/hiding-inherited-members
'programing' 카테고리의 다른 글
Python을 찾을 수 없습니다. 인수 없이 실행하여 Microsoft Store에서 설치하거나 설정에서 이 바로 가기를 사용하지 않도록 설정합니다. (0) | 2023.05.01 |
---|---|
UITableViewCell 사이에 간격을 추가하는 방법 (0) | 2023.05.01 |
IO 예외:파일 '파일 경로'가 다른 프로세스에서 사용되고 있기 때문에 프로세스에서 액세스할 수 없습니다. (0) | 2023.05.01 |
MongoDB Aggregation 오류: 파이프라인 단계 규격 개체는 정확히 하나의 필드를 포함해야 합니다. (0) | 2023.05.01 |
회귀 분석 f의 계수를 스프레드시트 또는 csv 파일로 내보내는 방법은 무엇입니까? (0) | 2023.05.01 |