3

私が書いているメソッドは、その中で別のオーバーロードされたメソッドを呼び出しています。外側のメソッドへのパラメーターが内側のメソッドに渡されるため、外側のメソッドを 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);
}

しかし、コードをコピーして貼り付けるのではなく、これを正しい方法で行いたいと思います。これを達成するための最良の方法は何ですか?

4

6 に答える 6

4

これはC++では実行できますが、C#では実行できません(内部メソッドがオーバーロードではなくジェネリックである場合を除く)。


あるいは(答えに「no」をとらない場合)、たとえば...のように、タイプのランタイムスイッチを実行できます。

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クラスを使用)が、これはおそらく価値があるよりも厄介です。

于 2009-01-07T23:44:05.387 に答える
2

他の人が言ったように、あなたはあなたがやろうとしていることを本当にすることはできません、そしてあなたがあなたの質問で述べたオプションは最善の策です。

ジェネリックを使用する場合は、実際に値を変換する必要があります。それ以外の場合は、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
            }

Genericsの概要へのリンクは次のとおりです。http://msdn.microsoft.com/en-us/library/ms172193.aspx

于 2009-01-08T00:06:34.700 に答える
1

型を使用して、dynamic実行時までオーバーロードの解決を延期できます。

public void OuterMethod(dynamic parameter)
{
    InnerMethod(parameter);
}

public void InnerMethod(int parameter) { }
public void InnerMethod(string parameter) { }

警告 型が dynamic の式は、コンパイラによって解決または型チェックされません。また、パフォーマンスが低下する可能性もあります。

于 2014-12-01T17:31:15.103 に答える
1

あなたの説明からすると、これは過剰な最適化のようです。

どうですか:

public void OuterMethod(string parameter)
{
    InnerMethod(parameter);
}

public void OuterMethod(int parameter)
{
    InnerMethod(parameter**.ToString()**);
}
于 2009-01-08T00:57:47.390 に答える
0

OuterMethod が常に InnerMethod を呼び出し、InnerMethod が int または string のみを受け入れる場合、OuterMethod<T> は意味がありません。

唯一の違いが、一方が 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)
{
    // ...
}
于 2009-01-07T23:59:31.143 に答える
0

わかりました、同様の状況があります。これは、ビジネス ロジックのアクセス制御方法です。

任意の永続レイヤー オブジェクトに適用できる保存機能があります。

それはこのように見えます

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 を使用して、「このエンティティをこのユーザーが作成できますか?」という質問により適したメソッドを探します。

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 か所で追加または削除するだけで済みます

于 2009-02-17T12:33:21.173 に答える