Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
Let's say we have a data object X and some "processor" objects/methods A, B, C and D. A(X) produces a new X with some additional data (the result of A processing). B(X) produces a new X with some other additional data. C(X) also produces a new X with some additional data but it requires that A has already been ran against X.
So: A(X).B(X).C(X).D(X) should run properly. B(X).D(X).A(X).C(X) should also run properly. B(X).C(X).A(X).D(X) should fail (because C requires the info A produces).
Is this possible to implement in C# so that the order constraints are enforced in compile time? If not, is there a design pattern or some common strategy of how this should be implemented? There can be many processors and many constraints, what I'd like to avoid is having to declare a factorial number of types to keep track of whether a processor has been ran or not.
You can use inheritance, combined with generic constraints:
class Data {
}
class ExtendedData : Data {
}
static class Pipeline {
public static ExtendedData A<T>(this T value) where T : Data {
if (value is ExtendedData extended) {
return extended;
}
else {
return new ExtendedData():
}
}
public static T B<T>(this T value) where T : Data {
return value;
}
public static ExtendedData C(this ExtendedData value) {
return value;
}
}
These variants will work:
new Data().A().B().C();
new Data().B().A().C();
new Data().A().C().B();
This variant will be rejected by the compiler:
new Data().B().C().A();
C() will expect an ExtendedData, while B() will only deliver Data.
Related
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 2 years ago.
Improve this question
I am trying to sort two objects by one of their properties (.Transaction.topLeftX, an integer) using the following code to create a comparer to use in a Sort method:
public class RespComp : IComparer<Kairos.Net.RecognizeImage>
{
public Kairos.Net.RecognizeImage Compare(Kairos.Net.RecognizeImage x, Kairos.Net.RecognizeImage y)
{
if (x.Transaction.topLeftX.CompareTo(y.Transaction.topLeftX) <= 0) return x;
else return y;
}
}
However, I get the error message Error CS0738 'RecogniseFacesKairos.RespComp' does not implement interface member 'IComparer.Compare(RecognizeImage, RecognizeImage)'. 'RecogniseFacesKairos.RespComp.Compare(RecognizeImage, RecognizeImage)' cannot implement 'IComparer.Compare(RecognizeImage, RecognizeImage)' because it does not have the matching return type of 'int'.
Does the comparer used in the Sort method need to have return type int?
The IComparer<T> interface is supposed to implement a method that returns an int comparison. -1 for less than, 0 for equal and 1 for greater than.
Look at your code, if you're just comparing the top left, you can probably just do the following:
public int Compare(FooImage x, FooImage y) {
return x.Transaction.topLeftX.CompareTo(y.Transaction.topLeftX);
}
The desired outcome of sorting objects by one of their parameters was achieved by the following code:
...
Kairos.Net.KairosClient client = new Kairos.Net.KairosClient();
client.ApplicationID = appId;
client.ApplicationKey = appKey;
Kairos.Net.RecognizeResponse resp = client.Recognize(...);
RespComp SortImages = new RespComp();
resp.Images.Sort(SortImages);
...
public class RespComp : IComparer<Kairos.Net.RecognizeImage>
{
public int Compare(Kairos.Net.RecognizeImage x, Kairos.Net.RecognizeImage y)
{
return x.Transaction.topLeftX.CompareTo(y.Transaction.topLeftX);
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
Ok, as my original question seemed a bit ambiguous because I was asking for a general question about the C# language, but showing part of a particular example where I was having a problem with it, I'm going to try to rewrite so that it is clearer that my question is about the C# language, not about my particular problem.
I currently have a property (several, in fact) of a class, that return a different value depending on whether you access them directly by code, or using reflection. This is what happens when I access the property using the immediate console of VS:
> SelectedLine.QtyOutstanding
0
> var prop = SelectedLine.GetType().GetProperty("QtyOutstanding")
> prop.GetValue(SelectedLine)
8
Regardless of how the property is defined, what is the difference, in C#, between both ways of accessing the property?
Shouldn't they both run exactly the same code in the setter/getter, if there is one?
(Considering that GetType() returns the same type as the variable is declared as)
I found a way to produce this, maybe your case looks like that?
If your SelectedLine is accessible via interface, and your class has an explicite implementation of that, but also has a public property with the same name, this could lead to different results.
Example
class Program
{
static void Main(string[] args)
{
var SelectedLine = (ILine)new Line(8);
Console.WriteLine(SelectedLine.QtyOutstanding); // 0
var prop = SelectedLine.GetType().GetProperty("QtyOutstanding");
Console.WriteLine(prop.GetValue(SelectedLine)); // 8
Console.ReadLine();
}
}
class Line : ILine
{
public Line(int qtyOutstanding)
{
QtyOutstanding = qtyOutstanding;
}
public int QtyOutstanding { get; }
int ILine.QtyOutstanding
{
get
{
return 0;
}
}
}
interface ILine
{
int QtyOutstanding { get; }
}
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 5 years ago.
Improve this question
For example:
public class Test
{
private string _s;
public Test()
{
var s = "hello";
_s = s;
}
public void Foo()
{
var s = _s;
// Use s for some reason.
}
}
Should I use _s directly for my needs or store _s into another variable that point to it? What if there were a property instead of the private field?
First, "encapsulate" is not at all the word for what you're doing. You're talking about making a copy. In programming, to "encapsulate" means to hide the field and make everybody access it via code of some kind. In C# that almost always means a property (which is really just method calls disguised by syntactic sugar). In other languages it might be explicit get and set methods.
So. Should you make a copy?
Yes:
private int _from = 9;
public void f(int to)
{
for (int i = _from; i < to; ++i)
{
// stuff
}
}
No:
public f2()
{
Console.WriteLine("from is {0}", _from);
}
If you're going to be changing the value as you use it, but you don't want the private field to be changed, make a local copy and change that.
But beware: Value types such as int behave very, very differently than mutable reference types such as SqlConnection (see below).
If you won't be changing it, don't waste your time. In fact, if the field is a reference type and you create a local reference to it, somebody maintaining your code ages hence may mistake it for a local object and wrongly assume that changes to it won't have class-wide effects.
private SqlConnection _conn = null;
public MyClass()
{
_conn = new SqlConnection();
}
public void f3()
{
var c = _conn;
// 150 lines of stuff
// OK, I guess we're done with it now!
c.Dispose();
c = null;
// Now _conn is not null, yet the next call to f3() will find it unexpectedly
// in an invalid state. You really don't want that.
}
Where did you get this idea from?
I see no reason to proxy the private field with a local variable. Most of the time, that field will be of a reference type (i.e., more or less, a class), so using a local variable only means one more reference to that object.
It could actually be harmful (anyway, doing unintended things) if you did that with a value-type field (an int, for example). You would act on the local variable, which is fine as long as you read it; but on write the field would not be changed.
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I've seen certain .NET properties only allow adding and removing elements from a list through the += and -= operators. How do I create a property of a class with that functionality?
If you are talking about Properties, there is no way how determine "syntax use" of your properties in following way:
Enable i += 1;
Disable i = i + 1;
You maybe mismatched it with "delegate and events" which uses syntax += for some operations. For more info about delegates and events you should look at http://msdn.microsoft.com/en-us/library/aa645739(v=vs.71).aspx for example.
EDIT: Last alternative I could think of is operator overloading but I haven't experience to refer about this specific situation so there is link with more info C# operator overload for `+=`? but I don't think so that this is exactly what are you looking for, because it will not put restriction on syntax usage of your properties
You can achieve a similiar effect by doing:
public class Test
{
private List<string> _myList;
public Test()
{
_myList = new List<string>();
}
public List<string> MyList
{
get { return _myList; }
}
public void ManipulateList()
{
_myList.Add("string 1");
_myList.Add("string 2");
}
}
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I am making a sort of statistical software that firstly needs to 'detect' the datatype of an array.
Firstly, X[,] is an array of sometype, can be all strings, all double, all ints or a combination of all.
Now, for every column X[] I need to know the datatype. Like:
If everything is 0 or 1, then Boolean (or binomial)
elseIf everything is integer, then integer
elseIf everything is double, then double
else: String
I need something like this in C#.
So it seems what you're trying to do here is find the "lowest common denominator" of types here. The most derived type that all of the items in the collection "are".
We'll start out with this helper method to get the entire type hierarchy of an object (including itself):
public static IEnumerable<Type> BaseClassHierarchy(object obj)
{
Type current = obj.GetType();
do
{
yield return current;
current = current.BaseType;
} while (current != null);
}
Now we can take a sequence of objects, map each to its hierarchy, intersect all of those sequences with each other, and then the first item of that result is the most derived type that is common to all of the other objects:
public static Type MostDerivedCommonType(IEnumerable<object> objects)
{
return objects.Select(o => BaseClassHierarchy(o))
.Aggregate((a,b)=> a.Intersect(b))
.First();
}
One simple idea is you can try to cast/parse as the different types and if that fails, move on to the next type. A very brief example of this is:
foreach (var element in myArray) {
double parsedDouble; int parsedInt;
var defaultValue = element.ToString();
if (Double.TryParse(defaultValue, out parsedDouble)) {
// you have something that can be used as a double (the value is in "parsedDouble")
} else if (Int32.TryParse(defaultValue, out parsedInt)){
// you have something that can be used as an integer (the value is in "parsedInt")
} else {
// you have something that can be used as an string (the value is in "defaultValue")
}
}
I believe that should probably get you started. Good luck!
Note
As other's have said - it is better to use strong types in C#. In most cases you can probably select a single type and use that rather than performing the checks above.