所以我知道有幾種方法可以讓其他類可以訪問私有欄位,我只是覺得它們必須是一種更簡單的方法,因為我可以在 C 中使用指標更容易地做到這一點。
基本上,我有一個包含大量整數的類,然后創建了許多使用這些整數的類。但是每個類只使用幾個整數。我想要的是允許每個類只訪問他們需要的變數,但讓所有剩余的整數都無法訪問。
基本上我會在 C 中做的是:
class PrivateClass
{
private:
int a, b, c, d;
public:
void DoStuff();
};
接著
void DoStuff()
{
ClassOne class_one(&a, &b);
ClassTwo class_two(&c, &d);
//stuff
}
因此class_one可以訪問a和b的值,而class_two可以訪問c和d的值。(另外,如果我在代碼中犯了任何錯誤,請原諒我,因為我已經有一段時間沒有真正用 C 撰寫了)
考慮到在那里做起來多么容易,這讓我覺得(也許是錯誤的)在 C# 中必須有一個類似的簡單方法。如果沒有,我將主要制作一個索引器來封裝變數,以便可以通過這種方式訪問??它們。
編輯:基本上我知道我應該只使用我一直奇怪避免的屬性。我不介意為幾個領域制作屬性,但出于某種原因,這樣做 30 左右感覺不對,好像應該有更好的方法。
uj5u.com熱心網友回復:
與另一個類共享私有變數的想法不太合理。有各種訪問修飾符,但是如果您希望一個類可以訪問某些成員,另一個類可以訪問不同的成員,等等,這將無濟于事。
所以第一個問題是如何共享變數。通常我們使用屬性來做到這一點。
在此示例中,另一個類可以讀取A但不能更改它。另一個類可以讀寫B。沒有可更改的屬性_c。如果我們想分叉,類之外的任何東西都不能真正讀取或更改變數。他們只能訪問屬性,而屬性讀取/寫入變數。(您也可以使用自動屬性來執行此操作。您不需要變數和單獨的屬性。但現在這無關緊要。)
class PrivateClass
{
private int _a;
private int _b;
private int _c;
public int A => _a;
public int B
{
get { return _b; }
set { _b = value; }
}
};
接下來,您希望能夠控制哪些類可以“看到”哪些變數。只要有屬性,就不能絕對阻止某人撰寫呼叫它們的代碼。但是您可以控制一個班級如何“看到”另一個班級。
這是一個人為的例子。這些型別沒有多大意義。
public class PublicTransportVehicle : IPublicTransport, IMotorVehicle
{
public int PassengerCapacity { get; private set; }
public int PassengerCount { get; set; }
public int AxleCount { get; private set; }
}
public interface IPublicTransport
{
int PassengerCapacity { get; }
int PassengerCount { get; set; }
}
public interface IMotorVehicle
{
int AxleCount { get; }
}
該類PublicTransportVehicle具有三個int屬性。兩個是只讀的。一是讀寫。(我使用了自動屬性而不是變數。這只是意味著如果set是私有的,那么只有類本身可以設定屬性。)
現在我可以撰寫一個帶有型別引數的方法的類IPublicTransport。我可以傳遞實作該介面的實體PublicTransportVehicle或任何其他類。但方法只見IPublicTransport。它知道的唯一屬性是該介面公開的屬性。
我可以撰寫另一個接受型別引數的方法,IMotorVehicle它只與該介面中定義的屬性互動。
我可以將 的實體傳遞PublicTransportVehicle給任一方法,因為它實作了這兩個介面,但每個人對它的看法不同。
我們可以絕對阻止呼叫者訪問我們不希望它訪問的屬性嗎?這要困難得多。例如,一個類可以這樣做:
public void DoSomethingWithMotorVehicle(IMotorVehicle motorVehicle)
{
var publicTransportVehicle = motorVehicle as PublicTransportVehicle;
if (publicTransportVehicle != null)
{
publicTransportVehicle.PassengerCount = 1000;
}
}
但我們通常不能也不應該費心嘗試完全控制它。這幾乎是不可能的。這個想法是傳達消費者期望與之互動的屬性和方法。我們通過故意使它們易于訪問來做到這一點。如果有人想要一些奇怪的東西,比如投射一個物件或使用反射,我們無能為力。除非這是與安全相關的嚴重問題,否則我們無需擔心。
uj5u.com熱心網友回復:
私有欄位、方法、屬性、建構式和事件都意味著僅供類使用。如果你想從其他類訪問這些欄位,你可以做這樣的事情:
using System;
namespace SharePrivateFields
{
class Supervisor
{
void DoStuff()
{
var subject = new Subject();
var first = new First(subject);
var second = new Second(subject);
}
}
class Subject : IFirstSubject, ISecondSubject
{
public int A { get; set; }
public int B { get; set; }
public int C { get; set; }
public int D { get; set; }
}
interface IFirstSubject
{
int A { get; set; }
int B { get; set; }
}
interface ISecondSubject
{
int C { get; set; }
int D { get; set; }
}
class First
{
private IFirstSubject _subject;
public First(IFirstSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // Completely correct
Console.WriteLine(_subject.C); // `IFirstSubject` does not contain definition for `C`
}
}
class Second
{
private ISecondSubject _subject;
public Second(ISecondSubject subject)
{
_subject = subject;
}
protected void DoMagic()
{
Console.WriteLine(_subject.A); // `ISecondSubject` does not contain definition for `A`
Console.WriteLine(_subject.C); // Completely correct
}
}
}
但是,我們現在正在涉足抽象工廠設計模式,在這種情況下,這是一種更理想的方法。
我確信你提到的 C 實作是一個有缺陷的設計,所以這就是為什么你不能在 C# 中讓它變得簡單的一個原因(如果我們完全誠實 - 你可以,閱讀不安全代碼,指標型別, 和函式指標;但對于 C# 代碼來說,這是 99% 的時間禁忌)。
因此,我建議您了解抽象工廠,或者至少將我的解決方案用于您的用例。
uj5u.com熱心網友回復:
將方法設為靜態并將相應的實體發送給它,然后您就可以訪問您想要的資料。
Static Void DoStuff(PrivateClass instance)
{
ClassOne class_one(instance.a, instance.b);
ClassTwo class_two(instance.c, instance.d);
//stuff
}
但事實是這是錯誤的,您應該向變數添加讀寫屬性,以便能夠從外部將它們作為引數發送到 DoStuff。
//in Main
PrivateClass pClass = new PrivateClass(1,30,2,19);
DoStuff(pClass.A, pClass.B, pClass.C, pclass.D);
//in PrivateClass
namespace Test
{
class PrivateClass
{
private int a;
private int b;
private int c;
private int d;
public PrivateClass(int a, int b, int c, int d)
{
this.a = a;
this.b = b;
this.c = c;
this.d = d;
}
public int A
{
get
{
return this.a;
}
set
{
this.a = value;
}
}//etc
public static void DoStuff(int a, int b, int c, int d)
{
ClassOne class_one(a, b);
ClassTwo class_two(c, d);
//stuff
}
}
}
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/490701.html
標籤:C#
