C# right way implement generic method - c#

I have some repeated pieces of code. This contradicts with DRY principe. But i don't know how replace this with generic method.
class Foo
{
public bool isFirstAttribHasRightValue;
public bool isSecondAttribHasRightValue;
private readonly T1 _firstAttrib;
private readonly T2 _secondAttrib;
public HashSet<T1> relatedToFirstAttrib;
public HashSet<T2> relatedToSecondAttrib;
...
public C()
{ ... }
public T1 GetFirstAttrib(T3 somevalue)
{
return (somevalue != othervalue) || isFirstAttribHasRightValue ? _firstAttrib : default(T1);
}
public T2 GetSecondAttrib(T3 somevalue)
{
return (somevalue != othervalue) || isSecondAttribHasRightValue ? _secondAttrib : default(T2);
}
public ClearRelatedToFirst()
{
isFirstAttribHasRightValue = true;
relatedToFirstAttrib.Clear();
}
public ClearRelatedToSecond()
{
isSecondAttribHasRightValue = true;
relatedToSecondAttrib.Clear();
}
...
}
I like to replace duplicate methods, like ClearRelatedToFirst() and ClearRelatedToSecond(), to ClearRelatedToAttrib<TYPE>(). And inside that generick method i don't know how to choose which bool-variable i need to set or which hashset i need to clear.
Same to other duplicate methods. Can you show me, how i can refactor this code?
Thanks.

See code below:
class Attribute<T>
{
public bool isRightValue;
public HashSet<T> relatedHashSet;
private T _value;
public T GetValue(T3 somevalue)
{
return (somevalue != othervalue) || isRightValue ? _value : default(T);
}
public Clear()
{
isRightValue = true;
relatedHashSet.Clear();
}
}
class Foo
{
public Attribute<T1> firstAttribute;
public Attribute<T2> secondAttribute;
...
public Foo()
{ ... }
...
}

Related

How to cast object to type specified by Type variable

I am looking for a way to cast object variable into type with generic type argument specified by other variable of type Type.
I am limited to .NET 3.5, so no dynamic can be used :(
Main idea here is that I have access to a dictionary:
Dictionary<Type, object> data;
Data to that dictionary is added only in form of:
data.Add(T, new DataSub<T>(someValueOfTypeT));
The problem is, that when I'm trying to reverse the process:
foreach(var dataType in data.Keys) {
var dataValue = data[dataType];
ProcessDataValue(dataType, dataValue);
}
Now the question is how do I manage to cast object to DataSub?
Simplified DataSub.cs:
public class DataSub<T>
{
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
}
How it could work in ProcessDataValue:
public void ProcessDataValue(Type dataType, object dataValue)
{
var data = dataValue as DataSub<dataType>;
if (data == null) return;
AddProcessedDataValue(dataType, data.Value.ToString());
}
if you can do minimal changes to the classes you posted and if - as is showed in your example - what you would do with DataSub.Value is invoking ToString, may be you can obtain the result you need with
public interface IDataSub {
bool MatchesType(Type t);
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public bool MatchesType(Type t) {
return typeof(T) == t; // or something similar, in order to handle inheritance
}
public object GetValue() {
return Value;
}
}
public class Client {
Dictionary<Type, IDataSub> data = new Dictionary<Type, IDataSub>() ;
public void AddData<T>(T someValueOfTypeT) {
data.Add(typeof(T), new DataSub<T> { Value = someValueOfTypeT });
}
public void UseData() {
foreach(var dataType in data.Keys) {
var dataValue = data[dataType];
ProcessDataValue(dataType, dataValue);
}
}
public void ProcessDataValue(Type dataType, IDataSub dataValue)
{
if(dataValue.MatchesType(dataType))
AddProcessedDataValue(dataType, dataValue.GetValue().ToString());
}
}
If the usage of DataSub.Value.ToString is only an example, and in the real world you need to access DataSub.Value using its type T, you should apply a broader reworking of you code.
What do you think about the following approach? This is an application of the pattern I like call set of responsibility (I wrote the linked post about this topic), a variation of GoF's chain of responsibility:
public interface IDataSub {
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public object GetValue() {
return Value;
}
}
public interface IDataHandler {
bool CanHandle(Type type);
void Handle(object data);
}
public class Client {
private readonly Dictionary<Type, IDataSub> data = new Dictionary<Type, IDataSub>();
private readonly IList<IDataHandler> handlers = new List<IDataHandler>();
public void AddData<T>(T someValueOfTypeT) {
data.Add(typeof(T), new DataSub<T> { Value = someValueOfTypeT });
}
public void RegisterHandler(IDataHandler handler) {
handlers.Add(handler);
}
public void UseData() {
foreach(var dataType in data.Keys) {
handlers.FirstOrDefault(h => h.CanHandle(dataType))?.Handle(data[dataType].GetValue());
}
}
// Lambda-free version
// public void UseData() {
// foreach(var dataType in data.Keys) {
// for (int i = 0; i < handlers.Count; i++) {
// if (handlers[i].CanHandle(dataType)) {
// handlers[i].Handle(data[dataType].GetValue());
// break; // I don't like breaks very much...
// }
// }
// }
// }
}
class StringDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of type
return typeof(string) == type;
}
public void Handle(object data) {
string value = (string) data;
// Do something with string
}
}
class IntDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of type
return typeof(int) == type;
}
public void Handle(object data) {
int value = (int) data;
// Do something with int
}
}
This approach allow you to decouple data storage and data iteration logic from data-handling logic specific of different data-types: IDataHandler's implementations known what type of data they can handle and cast generic object reference to desired type. If you prefer, you can merge CanHandle method into Handle method, remving the former method and changing UseData to
public void UseData() {
foreach(var dataType in data.Keys) {
foreach(var handler in handlers) {
handler.Handle(dataType, data[dataType].GetValue())
}
}
}
and handler implementations to
class IntDataHandler : IDataHandler {
public void Handle(Type dataType, object data) {
if(typeof(int) == type) {
int value = (int) data;
// Do something with int
}
}
}
This variant is slightly more type-safe, because in the first variant was already possibile to call Handle method without a previus call to CanHandle.
If you liked this approach, you can bring it forward, simplifying your data structure and converting data from IDictionary to IList:
public interface IDataSub {
object GetValue();
}
public class DataSub<T> : IDataSub {
private T _cache;
public T Value {
get { return _cache; }
set { _cache = value; }
}
public object GetValue() {
return Value;
}
}
public interface IDataHandler {
bool CanHandle(object data);
void Handle(object data);
}
public class Client {
private readonly IList<IDataSub> data = new List<IDataSub>();
private readonly IList<IDataHandler> handlers = new List<IDataHandler>();
public void AddData<T>(T someValueOfTypeT) {
data.Add(new DataSub<T> { Value = someValueOfTypeT });
}
public void RegisterHandler(IDataHandler handler) {
handlers.Add(handler);
}
public void UseData() {
foreach(var dataItem in data) {
var value = dataItem.GetValue();
handlers.FirstOrDefault(h => h.CanHandle(value))?.Handle(value);
}
}
// Lambda-free version as above...
class StringDataHandler : IDataHandler {
public bool CanHandle(object data) {
// Your logic to check if this handler implements logic applyable to instances of String
return data is string;
}
public void Handle(object data) {
string value = (string) data;
// Do something with string
}
}
class IntDataHandler : IDataHandler {
public bool CanHandle(Type type) {
// Your logic to check if this handler implements logic applyable to instances of int
return type is int;
}
public void Handle(object data) {
int value = (int) data;
// Do something with int
}
}
The CanHandle-free variant can simplify IDataHandler interface and its implementation in this case, too...
I hope my answer can help you resolving you design scenario; I build it upon an approach I like very much, because it allows to apply subtype-specific logic to instances of different classe, given they share a common superclass (as object in my code samples).

Specification pattern async

I'm trying to apply Specification pattern to my validation logic. But I have some problems with async validation.
Let's say I have an entity AddRequest (has 2 string property FileName and Content) that need to be validated.
I need to create 3 validators:
Validate if FileName doesn't contains invalid characters
Validate if Content is correct
Async validate if file with FileName is exists on the database. In this case I should have something like Task<bool> IsSatisfiedByAsync
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
My version of ISpecification (I need only And)
public interface ISpecification
{
bool IsSatisfiedBy(object candidate);
ISpecification And(ISpecification other);
}
AndSpecification
public class AndSpecification : CompositeSpecification
{
private ISpecification leftCondition;
private ISpecification rightCondition;
public AndSpecification(ISpecification left, ISpecification right)
{
leftCondition = left;
rightCondition = right;
}
public override bool IsSatisfiedBy(object o)
{
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
}
}
To validate if file exists I should use:
await _fileStorage.FileExistsAsync(addRequest.FileName);
How can I write IsSatisfiedBy for that check if I really need do that async?
For example here my validator (1) for FileName
public class FileNameSpecification : CompositeSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
{
return false;
}
if (request.FileName.Length > 1024)
{
return false;
}
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
{
return false;
}
return true
}
}
I need to create FileExistsSpecification and use like:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if(validations.IsSatisfiedBy(addRequest))
{ ... }
But how can I create FileExistsSpecification if I need async?
But how can I implement both IsSatisfiedBy and IsSatisfiedByAsync? Should I create 2 interfaces like ISpecification and IAsyncSpecification or can I do that in one?
You can define both synchronous and asynchronous interfaces, but any general-purpose composite implementations would have to only implement the asynchronous version.
Since asynchronous methods on interfaces mean "this might be asynchronous" whereas synchronous methods mean "this must be synchronous", I'd go with an asynchronous-only interface, as such:
public interface ISpecification
{
Task<bool> IsSatisfiedByAsync(object candidate);
}
If many of your specifications are synchronous, you can help out with a base class:
public abstract class SynchronousSpecificationBase : ISpecification
{
public virtual Task<bool> IsSatisfiedByAsync(object candidate)
{
return Task.FromResult(IsSatisfiedBy(candidate));
}
protected abstract bool IsSatisfiedBy(object candidate);
}
The composites would then be:
public class AndSpecification : ISpecification
{
...
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await leftCondition.IsSatisfiedByAsync(o) && await rightCondition.IsSatisfiedByAsync(o);
}
}
public static class SpecificationExtensions
{
public static ISpecification And(ISpeicification #this, ISpecification other) =>
new AndSpecification(#this, other);
}
and individual specifications as such:
public class FileExistsSpecification : ISpecification
{
public async Task<bool> IsSatisfiedByAsync(object o)
{
return await _fileStorage.FileExistsAsync(addRequest.FileName);
}
}
public class FileNameSpecification : SynchronousSpecification
{
private static readonly char[] _invalidEndingCharacters = { '.', '/' };
public override bool IsSatisfiedBy(object o)
{
var request = (AddRequest)o;
if (string.IsNullOrEmpty(request.FileName))
return false;
if (request.FileName.Length > 1024)
return false;
if (request.FileName.Contains('\\') || _invalidEndingCharacters.Contains(request.FileName.Last()))
return false;
return true;
}
}
Usage:
var validations = new FileNameSpecification().And(new FileExistsSpecification());
if (await validations.IsSatisfiedByAsync(addRequest))
{ ... }
I don't know, why you need async operations in a sync driven pattern.
Imagine, if the first result is false and you have two or more async checks, it would be a waste in performance.
If you want to know, how to get an async request back in sync, you can try to use the following:
public class FileExistsSpecification : CompositeSpecification
{
public override bool IsSatisfiedBy(object o)
{
var addRequest = (AddRequest)o
Task<bool> fileExistsResult = _fileStorage.FileExistsAsync(addRequest.FileName);
fileExistsResult.Wait();
return fileExistsResult.Result;
}
}
You should also use the generics approach.
I think your main goal here is to make sure that code finishes as soon as possible for evaluating a composite specification, when executing child specifications and one or more may take a while, yes? It's always possible for calling code outside of your pattern implementation to invoke a specification asynchronously; it's not really your concern at that point.
So, in light of that, how about giving your ISpecification an extra property?
public interface ISpecification
{
bool IsAsynchronous { get; }
bool IsSatisfiedBy(object o);
}
Then, for non-composite synchronous or asynchronous-type specifications, hard-code the return value for IsAsynchronous. But in composite ones, base it on the children, to wit:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!this.IsAsynchronous)
return leftCondition.IsSatisfiedBy(o) && rightCondition.IsSatisfiedBy(o);
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
But taking this a bit further, you don't want to waste performance. Hence why not evaluate the fast, synchronous child first when there's one sync and one async? Here's a closer-to-finished version of the basic idea:
public class AndSpecification : ISpecification
{
private ISpecification left;
private ISpecification right;
public AndSpecification(ISpecification _left, ISpecification _right)
{
if (_left == null || _right == null) throw new ArgumentNullException();
left = _left;
right = _right;
}
public bool IsAsynchronous { get { return left.IsAsynchronous || right.IsAsynchronous; }
public override bool IsSatisfiedBy(object o)
{
if (!left.IsAsynchronous)
{
if (!right.IsAsynchronous)
{
return left.IsSatisfiedBy(o) && right.IsSatisfiedBy(o);
}
else
{
if (!left.IsSatisfiedBy(o)) return false;
return right.IsSatisfiedBy(o);
}
}
else if (!right.IsAsynchronous)
{
if (!right.IsSatisfiedBy(o)) return false;
return left.IsSatisfiedBy(o);
}
else
{
Parallel.Invoke(
() => {
if (!left.IsSatisfiedBy(o)) return false;
},
() => {
if (!right.IsSatisfiedBy(o)) return false;
}
);
return true;
}
}
}

How to merge methods with the same body but different signatures together?

This is a refactoring question.
How to merge all these Check() methods into one single Generic Check() method since their method bodies are the same?
ppublic class ChangeDetector : IChangeDetector
{
private readonly IEqualityHelper _equalityHelper;
public ChangeDetector(IEqualityHelper equalityHelper)
{
_equalityHelper = equalityHelper;
}
public bool ChangeDetected { get; private set; }
public void Check<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new ()
{
if (!this._equalityHelper.Equals(existingList, newList))
{
NotifyChange();
}
}
public void CheckEntities<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new()
{
if (!this._equalityHelper.Equals(existingObj, newObj))
{
NotifyChange();
}
}
public void Check(string existing, string newVal)
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
public void Check<T>(T existing, T newVal) where T : struct
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
public void Check<T>(T? existing, T? newVal) where T : struct
{
if (!this._equalityHelper.Equals(existing, newVal))
{
NotifyChange();
}
}
private void NotifyChange()
{
ChangeDetected = true;
}
}
My EqualityHelper class members have different body though which is fine:
public class EqualityHelper : IEqualityHelper
{
public bool Equals<T>(IList<T> existingList, IList<T> newList) where T : IdentifiedActiveRecordBase<T>, new()
{
if (existingList == null || existingList.Count == 0)
{
if (newList != null && newList.Count > 0)
{
return false;
}
}
else
{
if (newList == null
|| existingList.Count != newList.Count
|| newList.Any(newListItem => existingList.Any(existingListItem => existingListItem.Id == newListItem.Id)))
{
return false;
}
}
return true;
}
public bool Equals<T>(IdentifiedActiveRecordBase<T> existingObj, IdentifiedActiveRecordBase<T> newObj) where T : IdentifiedActiveRecordBase<T>, new()
{
if (existingObj == null)
{
if (newObj != null)
{
return false;
}
}
else
{
if (newObj == null || existingObj.Id != newObj.Id)
{
return false;
}
}
return true;
}
public bool Equals(string existing, string newVal)
{
return string.Equals(existing, newVal);
}
public bool Equals<T>(T existing, T newVal) where T : struct
{
return !existing.Equals(newVal);
}
public bool Equals<T>(T? existing, T? newVal) where T : struct
{
if ((existing.HasValue && !newVal.HasValue)
|| (!existing.HasValue && newVal.HasValue)
|| existing.Equals(newVal))
{
return false;
}
return true;
}
}
The method bodies aren't really the same, since they're all calling different Equals() methods. What you're intending to do would (if I understand the question correctly) finish up with one Handle<T>() method where T could be any type. Thinking about what you're trying to express in the code, it seems fair that if you have one Handle<T>() method, that ought to be able to call one Equals<T>() method. That way, you can implement your handling logic once (and potentially this becomes more complex later but you only need to write it once) and you delegate the tricky business of comparing objects to your equality comparer class.
Just because the method bodies are looking similar doesn't mean the method signatures can be merged. Each of your five Handle methods calls five different Equals-methods, so unless you can merge the five Equals methods, you can't merge the Handle methods. You can't do that of course because the Equals method implementations are different. Remember that which of the Equals-method are to be called is decided compile-time, not runtime.
Edit: What you could do is change the signature of both Handle/Check and Equals to Check(object existing, object equals) and Equals(object existing, object equals). Then in the Equals-method perform a runtime type-check which results in a switch-case to the five Equals-method you already have with the help of type casting. This would make the implementation slower and only arguably more maintainable. I'm not sure I would go down that route.

Is there a technique to differentiate class behavior on generic types?

I'd like to do something like the following, but because T is essentially just a System.Object this won't work. I know T can be constrained by an interface, but that isn't an option.
public class Vborr<T> where T : struct
{
public Vborr()
{
public T Next()
{
if ( typeof( T ) == typeof( Double ) )
{
// do something for doubles
}
if ( typeof( T ) == typeof( Float ) )
{
// do something different for floats..
}
}
}
I frequently find C# generics lacking.
Thanks!
Paul
The whole point of generics is that you can do the same thing for any valid type.
If you're truly doing something specific for the types, then the method isn't generic anymore and should be overloaded for each specific type.
public class Vborr<T> where T : struct
{
public virtual T Next() { // Generic Implementation }
}
public class VborrInt : Vborr<int>
{
public override int Next() { // Specific to int }
}
public class VborrDouble : Vborr<double>
{
public override double Next() { // Specific to double }
}
The approach I would take here would be that of a factory pattern and creating specialized instances of Vborr based off of the type. For example
public class Vborr<T> where T : struct {
protected Vborr() { }
abstract T Next();
}
public static class VborrFactory {
private sealed class VborrFloat : Vborr<float> {
public VborrFloat() {}
public override float Next() {
...
}
}
private sealed class VborrDouble : Vborr<double> {
public VborrDobule() {}
public override double Next() {
...
}
}
private sealed class VborrDefault<U> : Vborr<U> {
public VborrDefault() {}
public override U Next() {
...
}
}
public static Vborr<T> Create<T>() {
if (typeof(T) == typeof(double) ) {
return new VborrDouble();
} else if ( typeof(T) == typeof(float) ) {
return new VborrFloat();
} else {
return new VborrDefault<T>();
}
}
}

ambiguous/conflicting constructors in generic class

I've got a generic class:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
//...
}
public BaseFieldValue(string value)
{
//...
}
public BaseFieldValue(T value)
{
//...
}
}
Fine. Except...
var myValue = new BaseFieldValue<string>("hello");
Oops. The undesired constructor is called. There's a number of ways to address the problem. What's the best solution?
I would probably make one of the overloads into a factory method:
public static BaseFieldValue<T> Parse(string value){}
You could do the following:
public class BaseFieldValue<T>
{
public struct Special
{
internal string m_value;
public Special(string value)
{
m_value = value;
}
}
public BaseFieldValue()
{
//...
}
public BaseFieldValue(Special value)
{
//...
}
public BaseFieldValue(T value)
{
//...
}
}
... or, you could add an extra ignored boolean parameter to your special constructor, just to disambiguate it.
Couldn't make Type Contraints do what I wanted, so my workaround is removing the ambiguous constructor while retaining the special case for string:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
//...
}
public BaseFieldValue(T value)
{
//however many things you need to test for here
if (typeof(T) == typeof(string))
{
SpecialBaseFieldValue(value.ToString());
}
else
{
//everything else
}
//...
}
private void SpecialBaseFieldValue(string value)
{
//...
}
}
A nasty hack, but probably no worse than any of the alternatives:
public class BaseFieldValue<T>
{
public BaseFieldValue()
{
// ...
}
public BaseFieldValue(StringWrapper value)
{
// ...
}
public BaseFieldValue(T value)
{
// ...
}
public class StringWrapper
{
private string _value;
public static implicit operator string(StringWrapper sw)
{
return sw._value;
}
public static implicit operator StringWrapper(string s)
{
return new StringWrapper { _value = s };
}
}
}
And now it can be used as you need:
// call the generic constructor
var myValue = new BaseFieldValue<string>("hello");
// call the string constructor
var myValue = new BaseFieldValue<int>("hello");
May be you can try thi:
var myValue = new BaseFieldValue<Object>("hello" as Object);

Categories

Resources