オーバーロードされたメソッドを呼び出すオーバーロードされたメソッド
-
05-07-2019 - |
質問
別のオーバーロードされたメソッドを呼び出すメソッドを記述しています。外部メソッドへのパラメーターが内部メソッドに渡されるため、外部メソッドを1つだけ記述したいと思います。これを行う方法はありますか?
ジェネリックを使用しようとしましたが、これについて十分に理解していないため、機能していません:
public void OuterMethod<T>(T parameter)
{
InnerMethod(parameter); // InnerMethod accepts an int or a string
}
これができることを知っています:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter);
}
しかし、コードをコピー/貼り付けするのではなく、正しい方法でやりたいと思います。これを達成する最良の方法は何ですか?
解決
これをC ++で行うことはできますが、C#ではできません(内部メソッドがオーバーロードではなくジェネリックである場合を除く)。
別の方法として(答えに「いいえ」をとらない場合)、タイプの実行時切り替えを行うことができます。たとえば、...
public void OuterMethod(object parameter)
{
if (parameter is int)
InnerMethod((int)parameter);
else if (parameter is string)
InnerMethod((string)parameter);
else
throw new SomeKindOfException();
}
...しかし、明らかにこれはランタイムであり、コンパイル時のチェックではありません。
しかし、コードをコピー/ペーストするのではなく、正しい方法でこれを行いたいです。
外部のメソッドを書くソフトウェア(たとえば、System.CodeDomクラスを使用する)を手動で書く代わりに書くこともできますが、これはおそらく価値があるよりも面倒です。
他のヒント
他の人が言ったように、あなたは自分がやろうとしていることを実際に行うことはできず、質問で述べた選択肢が最善の策です。
ジェネリックを使用する場合、実際に値を変換する必要があります。それ以外の場合は、ChrisWが示唆するようにオブジェクトを受け入れることでダウンキャストできます。
public void OuterMethod<T>(T parameter)
{
T temp = parameter;
if (temp is string )
InnerMethod(Convert.ToString(temp));
if (temp is int)
InnerMethod(Convert.ToInt32(temp));// InnerMethod accepts an int or a string
}
ジェネリックの概要へのリンクは次のとおりです。 http:// msdn .microsoft.com / en-us / library / ms172193.aspx
説明から、これは過剰に最適化されているようです。
方法:
public void OuterMethod(string parameter)
{
InnerMethod(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethod(parameter**.ToString()**);
}
dynamic
タイプを使用して、実行時までオーバーロード解決を延期できます。
public void OuterMethod(dynamic parameter)
{
InnerMethod(parameter);
}
public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }
警告 動的タイプの表現は解決されないか、コンパイラによってチェックされる型。また、パフォーマンスが低下する可能性があります。
OuterMethodが常にInnerMethodを呼び出し、InnerMethodがintまたは文字列のみを受け入れる場合、OuterMethod <!> lt; T <!> gt;意味がありません。
only の違いが、一方がInnerMethod(int)を呼び出し、もう一方がInnerMethod(string)を呼び出す場合、次のようにすることができます。
public void OuterMethod(string parameter)
{
InnerMethodA(parameter);
}
public void OuterMethod(int parameter)
{
InnerMethodA(parameter);
}
private void InnerMethodA(object parameter)
{
// Whatever other implementation stuff goes here
if (parameter is string)
{
InnerMethodB((string) parameter);
}
else if (parameter is int)
{
InnerMethodB((string) parameter);
}
else
{
throw new ArgumentException(...);
}
}
private void InnerMethodB(string parameter)
{
// ...
}
private void InnerMethodB(int parameter)
{
// ...
}
OK同様の状況があります。ビジネスロジックでのアクセス制御方法です。
任意の永続レイヤーオブジェクトに適用できる保存機能があります。
これは次のようになります
public static Save<T>(AccessControl.User user,T entity) where T:PersistanceLayerBaseClass
{
if(CanWrite(user, entity))
{
entity.save();
}
else
{
throw new Exception("Cannot Save");
}
}
アクセス制御の観点から特定のエンティティのカスタムコードがあるので、次のように書きました。System.Reflectionを使用して質問により適したメソッドを探します。<!> quot;このエンティティはこのユーザー?<!> quot;
public static Boolean CanWrite<T>(AccessControl.User user, T entity) where T : PersistanceLayerBaseClass
{
int? clubId = null;
MethodInfo methodInfo = entity.GetType().GetMethod("CanWrite", new Type[] { typeof(AccessControl.User), entity.GetType() });
if(methodInfo != null)
{
return (Boolean)methodInfo.Invoke(null, new object[] { user, entity }) ;
}
else
{
//generic answer
}
return HasRole(user.UserID, "Administrator") || (clubId.HasValue && user.MemberObject.ClubId == clubId.Value && HasRole(user.UserID, "AdministerClub"));
}
メソッドを追加または削除するたびに、1か所でメソッドを追加または削除するだけで済みます