Je souhaite ajouter une interface à certains types prédéfinis. J'ai une interface, IConcludable
, que j'utilise comme contrainte pour Conclusion<T>
. Je n'ai aucune idée de comment aborder cela, ou si c'est même possible.Existe-t-il un moyen d'étendre un type intégré pour hériter d'une interface?
Mise en page de base
public interface IConcludable { }
public struct Conclusion<T> where T : IConcludable
{
public bool IsSuccessful;
public T Result;
// Constructors, members, etc.
}
public class ErrorReport : IConcludable { ... }
public class MathArg : IConcludable { ... }
public class ParseResult : IConcludable { ... }
de mise en œuvre
public Conclusion<ParseResult> ParseInput (string input)
{
// Parse input...
// Initialize ParseResult object...
return new Conclusion<ParseResult>(result);
}
Problème
Quand je reçois la valeur finale, il est un type intégré comme int
, double
, string
, bool
, etc. Je voudrais utiliser Conclusion<T>
comme un retour parce que j'ai une classe qui gère les rapports d'erreur lorsque la chaîne d'entrée est invalide:
if (conclusion.ReturnObject is ErrorReport)
{
ErrorManager errorManager = new ErrorManager();
errorManager.Resolve(conclusion);
}
recherche
j'ai regardé contraintes.
Il semble que les contraintes ne font qu'ajouter ensemble, donc y compris les interfaces de chaque type intégré que j'ai besoin, il faudrait définir une montagne de méthodes qui n'ont rien à voir avec mon Conclusion
struct.
Méthodes d'extension
Ces facteurs modifient réellement le comportement des types intégrés. Ce n'est pas ce que je cherche car mon interface, IConcludable
, n'a pas de méthodes.
Remplacement types intégrés
pas possible. Je n'ai pas besoin de changer le comportement de ces types. Je veux juste ajouter une interface vide.
Il ne semble rien y avoir à ajouter une interface à un type intégré. Je ne suis pas sûr si "Héritage" est ce à quoi il serait fait référence. Est-ce possible?
Modifier
Une meilleure explication de struct Conclusion
J'utilise la struct conclusion comme un objet de retour dans la plupart de mes méthodes. C'est parce que j'utilise des délégués. Voir le code actuel des objets ci-dessous:
public delegate Conclusion<T> Validator<T>(T subclass) where T : IVerifiable<T>;
public delegate Conclusion<BaseFunction> Executor(BaseFunction subclass);
public struct Conclusion<T> where T : IConcludable
{
public bool IsSuccessful;
public T ReturnObject;
public Conclusion(T returnObject)
{
this.ReturnObject = returnObject;
this.IsSuccessful = returnObject is Error ? false : true;
}
}
public class BaseFunction : IVerifiable<BaseFunction>, IConcludable
{
public List<BaseArgument> Args;
public Executor Executing;
public Validator<BaseFunction> Validating;
public string UserInput;
public Conclusion<BaseFunction> Validate(BaseFunction subclass)
{
if (this.Validating != null)
{
return Validating(subclass);
}
else
{
StringBuilder message = new StringBuilder();
message.Append("A Validating delegate has not been assigned.");
throw new InvalidOperationException(message.ToString());
}
}
public Conclusion<BaseFunction> Execute(BaseFunction subclass)
{
if (this.Executing != null)
{
return this.Executing(subclass);
}
else
{
StringBuilder message = new StringBuilder();
message.Append("An Executing delegate has not been assigned.");
throw new InvalidOperationException(message.ToString());
}
}
}
public class Function<T> : BaseFunction
{
public T Result;
public Function()
{
base.Args = new List<BaseArgument>();
}
}
public class BaseArgument : IVerifiable<BaseArgument>, IConcludable
{
public string Role;
public string UserInput;
public int Position;
public Validator<BaseArgument> Validating;
public Conclusion<BaseArgument> Validate(BaseArgument subclass)
{
if (this.Validating != null)
{
return Validating(subclass);
}
else
throw new InvalidOperationException();
}
}
public class Argument<T> : BaseArgument
{
public T Value;
public Argument(int position)
{
base.Position = position;
}
}
public static class ExecutionHandler
{
public static Conclusion<BaseFunction> Sum(BaseFunction subclass)
{
subclass = (Function<double>)subclass;
// Execution code.
return new Conclusion<BaseFunction>(subclass);
}
public static Conclusion<BaseFunction> Concatenate(BaseFunction subclass)
{
subclass = (Function<double>)subclass;
// Execution code.
return new Conclusion<BaseFunction>(subclass);
}
}
Si j'ai besoin de poster plus, je le ferai. mais c'est vraiment beaucoup à regarder. Le type de retour des méthodes assignées par tous les délégués que j'utilise a un type de retour de Conclusion<T>
afin que je puisse avoir un objet de retour ainsi qu'une erreur s'il y en a une. Les fonctions dans le code ci-dessus renvoient Conclusion<BaseFunction>
, mais ce retour est converti en un objet Addend<T>
s'il s'agit d'un nombre. S'il fait partie d'un autre type de fonction qui renvoie un ou un bool
ou un autre type, il est converti en un type de classe différent. À la fin d'un calcul numérique, le retour sera quelque chose comme Conclusion<int>
ou Conclusion<double>
. Donc, ajouter int
et double
à l'interface IConcludable
est ce que j'essaie de faire.
Une meilleure explication de l'application
Je vous écris une application console C#. Il prend l'entrée de l'utilisateur, et écrit une réponse. L'entrée est similaire aux formules Excel: Sum(5, 15, Average(2, 3), 5)
ou Concatenate("5 + 5 = ", Text(Sum(5, 5)))
. La chaîne d'entrée est validée, analysée et renvoie un résultat.
comme je le vois dans votre implémentation, vous retournez Conclusion. Mais vous avez aussi dit *** Quand j'obtiens la valeur finale, c'est un type intégré comme int, double, string, bool, etc ***, je ne comprends pas cette partie. –
Bien que votre question soit très bien posée, je pense que vous devriez affûter la * question * que vous avez, car actuellement ce n'est pas clair ce qui ne fonctionne pas avec cette construction. –
N'est-ce pas un scénario pour ** Modèle d'adaptateur **? –