|
Taking the example below, this should do it:
Values.Select(
p =>
new
{
avg = Values.Skip(1).Take(Values.Count - 1)
.Where(x => Math.Abs(x) > double.Epsilon)
.Zip(Values, (second, first) => (second - first)/second)
.Average()
})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First();
This space for rent
|
|
|
|
|
It depends what you want the percentage change to be when one of the values is zero.
Assuming you want it to be 1 , the ternary operator should do the trick:
decimal average = lValues.Skip(1)
.Zip(lValues, (second, first) => second == 0 ? 1 : (second - first) / second)
.Average();
"These people looked deep within my soul and assigned me a number based on the order in which I joined."
- Homer
|
|
|
|
|
The evil side in me likes a challenge. I had a little bit of a play around and came up with this (where we assume that Values is your list of double value inputs; this copes with arbitrary lengths of Values as long as it's greater than 2):
Values.Select(
p =>
new {avg = Values.Skip(1).Where(x => index < Values.Count).Select(x => (x - Values[index++])/x).Average()})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First(); Taking inspiration from Richard's excellent answer, this can be further simplified into:
Values.Select(
p =>
new
{
avg = Values.Skip(1).Take(Values.Count - 1)
.Zip(Values, (second, first) => (second - first)/second)
.Average()
})
.Select(x => new {x, last = Values.Last()})
.Select(@t => new {@t, aver = @t.last + (@t.last*@t.x.avg)})
.Select(@t => new {value1 = @t.aver, value2 = @t.aver + (@t.aver*@t.@t.x.avg)}).First();
This space for rent
modified 29-Aug-17 10:25am.
|
|
|
|
|
Dear experts
I am somewhat "c++ corrupted". With this background I'm looking for a replacement for c++ const stuff in c#.
I don't look for a solution. First and foremost, this question I ask to get an assessment of the class design from you.
What I need/I try to solve:
I have a class Spectrum (basically a vector of doubles) for which I need full access for some tasks of the app(means manipulate each value of the vector) while other tasks should only have the possibility to read the values.
public class Spectrum
{
private readonly List _values;
public double this[int lambda]
{
get
{
return _values[lambda];
}
set
{
_values[lambda] = value;
}
}
}
[Edit]
The target is to protect some data from unintentional/Programme mistaken modifications
[/Edit]
Approach I.
For a first approach I thought I introduce an interface IConstSpectrum which hides the setter and will be used where I like to return a read only Spectrum.
But like in c++ one can cast the interface and have afterwards full access (in c++ this means a dirty const_cast)
Approach II.
a.) I introduce a class ConstSpectrum ...
public class ConstSpectrum
{
protected readonly List _values;
public double this[int lambda]
{
get
{
return _values[lambda];
}
}
}
b.) ... and derive from this the full accessible spectrum
public class Spectrum: ConstSpectrum
{
public double this[int lambda]
{
set
{
_values[lambda] = value;
}
}
}
Conclusion Approach II:
Depending on the task , I would use ConstSpectrum or Spectrum. And I'm Aware returning a Spectrum as ConstSpectrum opens the door to cast again.
Questions, resp, how do you see this:
- What do you think about this design? Is it overkill?
- Is there a better or maybe more easy solution?
Thank you very much in advance.
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
You could use a protected or internal setter: that would restrict the access to classes derived from ConstSpectrum or in the same assembly respectively. There is also protected internal which allows both derived and same assembly, basically.
Bad command or file name. Bad, bad command! Sit! Stay! Staaaay...
AntiTwitter: @DalekDave is now a follower!
|
|
|
|
|
Thank you very much for this Inputs. I will check what that means in Details.
Thanks again.
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
I read about internal (I think protected only does not help me). If I understand it correctly internal restricts the Access to the assembly (or maybe the Name space) where the class Spectrum is implemented.
So for me I think it will not help, because this class Spectrum/ConstSpectrum Needs to be available for several (a lot of) assemblies and especally also for the application itself.
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
With any approach one could also argue "but what about reflection" (or unsafe even).. just as in C++, there is no protection against intentional misuse of these classes, whether that means uncovering the "secret identity" of an object and casting to it or some more nefarious sort of "unauthorized poking around in private bits".
Hiding the existence of the setter with an interface already protects against unintentional abuse, so I would say that's enough.
|
|
|
|
|
Thank you very much. Yep, the Interface I think should really do it because as you mentioned there is always a way to break the rules.
I did this (breaking the rules) more than one times in c++ for legacy third party libraries whith bugs. In worst case I did #define privat public to make a Workaround
Thank you again.
Bruno
[Edit]
Reading this againQuote: Hiding the existence of the setter with an interface already protects against unintentional abuse, so I would say that's enough.
[/Edit]
modified 19-Jan-21 21:04pm.
|
|
|
|
|
0x01AA wrote: But like in c++ one can cast the interface and have afterwards full access (in c++ this means a dirty const_cast)
If you do not trust your users then you cannot directly expose the data at all.
It should only be exposed to the class and all public access, whether modifiable or not, should be via wrapper classes. Those wrapper classes provide appropriate methods. For the non-modifiable form the wrapper class should contain a copy of the array.
Might note that the first condition above, that of trust, I believe should be address via non-technological means via code reviews and management dictates.
|
|
|
|
|
Thank you for your reply.
Quote: you do not trust your users then you cannot directly expose the data at all.
I trust them, it is most for internal use...
... but you bring back into my mind to think more realistic/pragmatic:
The protection should be only to prevent from unintentional modification. This again in my mind tells me, my target to make it readonly more than by the help of a IConstInterface is Overkill.
Sometimes I Need to be waked up
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
Have you considered putting the core functionality in an inner class, inside the public class that exposes the operations you want people to be able to use?
This space for rent
|
|
|
|
|
Thank you for your reply.
Sorry, I don't understand. The Information of the class Spectrum should be available to anybody (read only) but only full Access for a certain "core". But I really don't like to manage Access by the help of assembly Organisation.
Can you give me some more hints how to structure this?
[Edit]I'm absolute beginner in c#[/Edit]
Thank you
Bruno
modified 19-Jan-21 21:04pm.
|
|
|
|
|
Use a "producer-consumer" pattern.
You're using "lists" anyway; create your collection and wrap it in a ReadOnlyCollection<t> for the (read-only) consumers.
(I recently switched to lists for some of my arrays when I noticed no significant difference for my requirements.)
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Beyond the protected and internal modifiers mentioned by others which are useful when the "full access" tasks remain inside the same dll, I'd use an approach similar to your first approach when both access types are needed in other dlls also. In short, it is called "interface segregation " and is the I of SOLID .
public interface IReadOnlySpectrum
{
double this[int lambda] { get; }
}
public interface IWritableSpectrum : IReadOnlySpectrum
{
new double this[int lambda] { get; set; }
}
public class Spectrum : IWritableSpectrum {...} Depending on the required access level, pass the instance as an IReadOnlySpectrum or as an IWritableSpectrum . It is true that a cast from IReadOnlySpectrum to IWritableSpectrum is possible, but well, if you do so, you should know that you sacrifice the safety introduced with interface segregation.
Also take care when it comes to reference types instead of value types like double : though the list may know be write-protected, its items are not. You may need to apply the double-interface trick above again with those types.
|
|
|
|
|
Thank you very much for this.
modified 19-Jan-21 21:04pm.
|
|
|
|
|
Hi,
I have to create .NET COM dll which will be used fro existing client applications.
So what I need is :
- create interface with SAME NAME AND GUID
- create class implementing this interface ann have SAME NAME AND GUID as one in c++
- client should not rebuild or recompiled (save compatibility)
Any help please
|
|
|
|
|
Extract the type library from your COM DLL. Use tlbimp.exe to import this typelibrary (it will create this as a separate assembly which you might want to reintegrate back into your code using a tool such as Reflector).
This space for rent
|
|
|
|
|
thank you for response but can you tell me how extracting tlb from c++ com because tlbExp not works
|
|
|
|
|
Really? Your first thought wasn't to go to Google for this[^]?
This space for rent
|
|
|
|
|
A Batch file to make it more easy to Register the COM visible assembly and create the tlb:
RegMyComVisible.bat
echo off
cd %~dp0
rem The following two path you Need to adjust to your needs
set regasm_tool= "C:\Windows\Microsoft.NET\Framework\v4.0.30319\RegAsm.exe"
set assembly= "C:\YourProject\YourComVisible.dll"
rem unregister previous version
%regasm_tool% %assembly% /u
rem Register actual Version and create a YourComVisible.tlb
%regasm_tool% %assembly% /codebase /tlb
pause
Make sure to run it as admin: Right Click RegMyComVisible.bat and select "Run As Admin".
I hope it helps.
modified 19-Jan-21 21:04pm.
|
|
|
|
|
But my COM dll is C++ dll and couldn't be registred as you say .
|
|
|
|
|
From the following as a potential new feature in C#
C# 8.0 Previewed[^]
As I understand it, which could very well be wrong, it works like the following
1. An existing class exists
2. Some other code 'adds' an interface to 1 via an extension modeling a method in that class.
Presumably the point of doing this in the first place is because one doesn't control the original class in the first place. So there is no control over how or when the original class might change.
Above works fine as long as the original class doesn't ever change, or at least the method doesn't. If it does then, presumably it results in a runtime failure of some sort.
Conversely other extensions would not normally suffer from this problem because they are additions only.
Probably not a problem as long as one's code base only contains a couple of these but if someone (or several someones) get carried away seems like a unexpected failure being coded in.
|
|
|
|
|
As I understood it, you have an Interface that you want to add something to.
public interface ISomething
{
void SomeMethod();
void NewMethod();
}
You can't add anything to the interface because this is a breaking change to all implementing classes of that interface. All the classes would be required to supply an implementation of the NewMethod.
This is where Interface Extensions come in. In order for this to work and not be a breaking change to all existing implementors, the new method signature in the Interface would have to supply a default implementation. The problem with this is that you can only use the terms of the existing Interface you're extending.
public interface ISomething
{
void SomeMethod();
}
public extension interface ISomethingEx : ISomething
{
void NewMethod()
{
... some default implementation;
}
}
I can see the up-side to this, but the downside is you're getting into what an Interface isn't, an implementation. I agree that this would be something that could easily be abused, making the code much harder to read, follow, and debug.
|
|
|
|
|
My biggest concern with that idea is that they blur the differentiation between an interface and an abstract class .
An interface used to be a pure abstract class (i.e. no implementation at all), so what's the difference now?
And the article also says that it is a way for multiple inheritance . Well, the Diamond of Death can be solved (so multiple inheritance could be a feature of the .Net world, as with unmanaged C++), but the article does not say anything about the solution used here.
And how will that be compatible with methods defined in two interfaces, with classes implementing both of them? When interfaces were pure abstract classes, that was no problem at all. And now?
|
|
|
|