生データのセットを含むクラスAと、そのデータの再編成されたバージョン(GUI対応)を含むクラスBがある場合、Aの生データをBで表示したいと思います。
明らかに、クラスAの生データはプライベートメンバーに含まれています。C ++のフレンドクラスメソッドに似たものを使用して、そのデータをBで表示できるようにしたいと思います。
どうすればこれにアプローチできますか?
ありがとうございました。
生データのセットを含むクラスAと、そのデータの再編成されたバージョン(GUI対応)を含むクラスBがある場合、Aの生データをBで表示したいと思います。
明らかに、クラスAの生データはプライベートメンバーに含まれています。C ++のフレンドクラスメソッドに似たものを使用して、そのデータをBで表示できるようにしたいと思います。
どうすればこれにアプローチできますか?
ありがとうございました。
厳密に言えば、データを公開できる特定のクラス(またはクラスのリスト)を定義することはできません。ただし、のinternal
代わりにアクセス修飾子を使用できprivate
ます。これにより、同じアセンブリ内のすべてのクラスでメンバーを使用できるようになります。
そうは言っても、フィールドではなくプロパティを介してこれらのメンバーを公開することを強く検討する必要があります(これは、公開を計画していると私が推測していることです)。これを行うことで、クラスは、その情報を他のクラスに公開する方法と、別のクラスがデータを変更したときに何が起こるかを正確に定義できます。
これはあなたを助けるかもしれません。
public class A
{
public A() { }
public string AccessData(object accessor)
{
if (accessor is B)
return "private_data";
else
throw new UnauthorizedAccessException();
}
}
public class B
{
public B() { }
private void AccessDataFromA()
{
Console.WriteLine(new A().AccessData(this));
}
}
アセンブリで両方を定義し、Aのフィールドを「内部」としてマークすることができます。
よりオブジェクト指向のアプローチは、通常は単純なプロパティを介して、データ(またはデータのサブセット)へのアクセスを可能にする一連のパブリックメソッドをAに提供することです。
構造によっては、Partialクラスを使用できる場合があります。これは、データとUIが実際には両方とも同じクラス内にあるが、異なるファイル内にあることを意味します。
それがうまくいかない場合は、代わりに内部スコープ変数を使用するか、UIがより一般的な方法で表すデータセットを操作します。
古いメソッド(しゃれを意図した)は、単純なgetvalue( )関数とsetvalue()関数を定義してその値を返すことで、これらの関数を使用しないとこれらの値にアクセスできなくなります。C#では、これらの関数はプロパティと呼ばれる事前定義されたメンバーです。
class TestMethod{
private int Secret;
get { return Secret;}
set { Secret = value;}
}
もう1つの方法は、他の人が私の前に述べたように、internal
修飾子を使用することです。
別のアプローチは、これらの線に沿ったものです。ここでのgetterとsetterは、クラスBをキーとして指定しているため、他のクラスがクラスAの内部状態に到達できないことに注意してください。
public class Program
{
public static void Main()
{
var a = new A(29);
var (getter, setter) = A.GetAndSetOnlyForB(a);
Console.WriteLine(getter(new B())); // 29
setter(new B(), 2);
Console.WriteLine(getter(new B())); // 2
getter(new C()); // compile error, cannot do that
setter(new C(), 9); // compile error, cannot do that
}
}
sealed class A
{
private int _hiddenInt;
public A(int hiddenInt)
{
_hiddenInt = hiddenInt;
}
public static (Func<B, int>, Action<B, int>) GetAndSetOnlyForB(A obj)
{
return ((key) => obj._hiddenInt, (key, arg) => { obj._hiddenInt = arg; });
}
}
sealed class B
{
}
sealed class C
{
}