C# 7 ValueTuple compile error - c#

I'm using VS2017 RC and my application targets net framework 4.6.1.
I have two assemblies referencing System.ValueTuple 4.3
MyProject.Services
MyProject.WebApi
In MyProject.Services I have a class with a method like this
public async Task<(int fCount, int cCount, int aCount)> GetAllStatsAsync()
{
// Some code...
return (fCount, cCount, aCount);
}
In MyProject.WebApi I have a controller that use this method like that:
public async Task<HttpResponseMessage> GetInfoAsync()
{
// Some code...
var stats = await _myClass.GetAllStatsAsync();
var vm = new ViewModel
{
FCount = stats.fCount,
CCount = stats.cCount,
ACount = stats.aCount
};
return Request.CreateResponse(HttpStatusCode.OK, vm);
}
Intellisense is working and deconstruct the tuple but when I compile it fails without any Error in Error List window.
In the output windows I have this errors:
2>MyController.cs(83,31,83,40): error CS1061: 'ValueTuple' does not contain a definition for 'fCount' and no extension
method 'fCount' accepting a first argument of type 'ValueTuple' could be found (are you missing a using directive or an
assembly reference?) 2>MyController.cs(84,39,84,49): error CS1061:
'ValueTuple' does not contain a definition for 'cCount'
and no extension method 'cCount' accepting a first argument of type
'ValueTuple' could be found (are you missing a using
directive or an assembly reference?) 2>MyController.cs(85,35,85,40):
error CS1061: 'ValueTuple' does not contain a
definition for 'aCount' and no extension method 'aCount' accepting a
first argument of type 'ValueTuple' could be found (are
you missing a using directive or an assembly reference?)
I tried adding the DEMO and DEMO_EXPERIMENTAL build flags but still fails.
Any idea on what's wrong?
EDIT 1:
This code works and stats is well deconstructed. I'm probably hitting a bug.
public async Task<HttpResponseMessage> GetInfoAsync()
{
// Some code...
var stats = await _myClass.GetAllStatsAsync();
var tu = stats.ToTuple();
var vm = new ViewModel
{
FCount = tu.Item1,
CCount = tu.Item2,
ACount = tu.Item3
};
return Request.CreateResponse(HttpStatusCode.OK, vm);
}
EDIT 2:
Issue open on github here: https://github.com/dotnet/roslyn/issues/16200

If anyone falls in the same trap, to fix this you need to update this package:
Microsoft.Net.Compilers to 2.0 (you need to show pre-release)

I just want to add to the other answers.
Remove System.valuetuple from references. Otherwise, it doesn't work and I do not know why. Basically, value tuple is already in 4.7.2 and so if you use visual studio 2019 you're all set.
If you use visual studio 2019 and I did, that's what worked for me. I don't exactly know why. No need for nugget. No need to reference that directly.
Target your project to use .net framework 4.7.2 and remove references to valuetuple.

I think It is because you've not defined fCount, cCount and aCount. Try this
public async Task<(int fCount, int cCount, int aCount)> GetAllStatsAsync()
{
// Some code...
//fCount, cCount, aCount are not defined here, so you should define them
var fCount = 0;
var cCount= 0;
var aCount = 0;
return (fCount , cCount, aCount );
//Other ways:
//return (fCount : 0, cCount: 0, aCount : 0);
//return new (int fCount , int cCount, int aCount ) { fCount = 0, cCount = 0, aCount = 0 };
}
public async Task<HttpResponseMessage> GetInfoAsync()
{
// Some code...
var stats = await _myClass.GetAllStatsAsync();
var vm = new ViewModel
{
FCount = stats.fCount,
CCount = stats.cCount,
ACount = stats.aCount
};
return Request.CreateResponse(HttpStatusCode.OK, vm);
}
Edited with #Swell suggestion
Take a look at this post

My problem was not at compile error, but during runtime.
But I suspect the fix is still valid and could help somebody here too.
After switching my project to .Net framework 4.7.2 I had to manually update the hintpath for System.ValueTuple from net461 to net47
<HintPath>..\Solutions\packages\System.ValueTuple.4.5.0\lib\net47\System.ValueTuple.dll</HintPath>

Related

how can i activate function update

the problem i have are
Assets\Scripts\Gunfire.cs(1,1): error CS0246: The type or namespace
name 'function' could not be found (are you missing a using directive
or an assembly reference?)
Assets\Scripts\Gunfire.cs(1,10): error CS0116: A namespace cannot
directly contain members such as fields or methods
the script is
function Update
{
get
{
if (Input.GetButtonDown("Fire1"))
{
var;
{ gunsound; }
AudioSource = GetComponent.AudioSource();
gunsound.Play();
GetComponent.Animation > (Play("GunShot"));
}
}
}
thank you very much
function is not a C# keyword. It looks like youa re trying to write JavaScript maybe.
C# function syntax is like this:
{returnType} {methodName} ({parameters}) { {body} }
int Add (int x, int y) { return x + y; }
In C# all functions must belong to a class. (This may change in C#9)
You can see an example of this if you create a new C# console app in Visual Studio.

How do I replace Consumes and Produces in Swashbuckle 5.0.0 using ASP.NET Core 3.1?

I need to refactor some C# code using Swashbuckle 4.0.1 and ASP.NET Core 2.0. I have to use Swashbuckle 5.0.0 and ASP.NET Core 3.1, however, I'm not able to solve the error I get from Consumes and Produces. The snippet I need to refactor is this:
public void Apply(OpenApiOperation operation, OperationFilterContext context) {
var produces = context.ApiDescription.TryGetMethodInfo(out var mInfo) ? mInfo.DeclaringType.GetCustomAttributes(true).OfType<ProducesAttribute>().FirstOrDefault() : null;
if (produces != null) {
operation.Consumes.Clear(); /* ERROR */
operation.Consumes = produces.ContentTypes.ToList(); /* ERROR */
operation.Produces.Clear(); /* ERROR */
operation.Produces = produces.ContentTypes.ToList(); /* ERROR */
}
foreach (var parameter in operation.Parameters) {
var description = context.ApiDescription.ParameterDescriptions.First(p => p.Name == parameter.Name);
if (string.IsNullOrEmpty(parameter.Name))
parameter.Name = description.ModelMetadata?.Name;
if (parameter.Description == null && description.RouteInfo != null)
parameter.Description = description.ModelMetadata?.Description;
if (description.RouteInfo != null)
parameter.Required |= !description.RouteInfo.IsOptional;
}
}
I'm not able to understand how to get rid of those errors. The errors I obtain from Visual Studio are:
Error CS1061 OpenApiOperation does not contain a definition for Consumes (the same happens with Produces) and no accessible extension method Consumes accepting a first argument of type OpenApiOperation could be found (are you missing a using directive or an assembly reference?)
You would have to decorate your controllers with Produces/Consumes attributes. See this GitHub issue: https://github.com/domaindrivendev/Swashbuckle.AspNetCore/issues/1296

TryGetObjectByKey not compiling in .net 4.5

I have the following code that does a great job at saving a detached object in a .Net 4 / EF 4 project. I wanted to use that code in a new .Net 4.5 / EF 5 project. I copied it in and now it gives me a compile error of:
"MyEntities does not contain a definition for 'TryGetObjectByKey' and no extension method 'TryGetObjectByKey' accepting a first argument of type MyEntities could be found (are you missing a using directive or an assembly reference?)"
Allegedly it is in the System.Data.Objects namespace (so I have a using for it) from the System.Data.Entity assembly (.dll) which is referenced.
public bool UpdateChanged(IEntityWithKey DetachedObject = null) {
bool Result = false;
try {
using (MyEntities db = new MyEntities()) {
if (DetachedObject != null) {
object Original = null;
if (db.TryGetObjectByKey(DetachedObject.EntityKey, out Original))
db.ApplyCurrentValues(DetachedObject.EntityKey.EntitySetName, DetachedObject);
} // if they want to Update an Entity
db.SaveChanges();
Result = true;
} // using the database
} catch (Exception e) {
} // try-catch
return Result;
} // UpdateChanged - Method
According to this link it should work: http://msdn.microsoft.com/en-us/library/bb738728.aspx
Can you please help?
UPDATE / SOLUTION:
Based on #Rowan's answer below I have simply modified my Save method to something like the following instead of creating an UpdateChanged method that takes Detached objects:
using (MyEntities db = new MyEntities()) {
if (o.ID > 0) {
// Existing Owner
db.Owners.Attach(o);
db.Entry(o).State = EntityState.Modified;
db.Entry(o.Address).State = EntityState.Modified;
} else {
// New Owner
db.Owners.Add(o);
} // if this is a New Owner
db.SaveChanges();
} // using the database
TryGetObjectByKey is a method on ObjectContext. Starting in Visual Studio 2012 new models will generate a DbContext based context by default (DbContext is designed to be a simpler and more intuitive API surface). Existing models will keep generating ObjectContext unless you choose to swap to DbContext. You can also revert back to ObjectContext for new models.
You can always get at the underlying ObjectContext using ((IObjectContextAdapter)db).ObjectContext.TryGetObjectByKey(...).

C# Getting Parent Assembly Name of Calling Assembly

I've got a C# unit test application that I'm working on. There are three assemblies involved - the assembly of the C# app itself, a second assembly that the app uses, and a third assembly that's used by the second one.
So the calls go like this:
First Assembly ------> Second Assembly---------> Third Assembly.
What I need to do in the third assembly is get the name of the Fist Assembly that called the second assembly.
Assembly.GetExecutingAssembly().ManifestModule.Name
Assembly.GetCallingAssembly().ManifestModule.Name
returns the name of the Second assembly.
and
Assembly.GetEntryAssembly().ManifestModule.Name
return NULL
Does anybody know if there is a way to get to the assembly name of the First Assembly?
As per the other users demand here I put the code. This is not 100% code but follow of code like this.
namespace FirstAssembly{
public static xcass A
{
public static Stream OpenResource(string name)
{
return Reader.OpenResource(Assembly.GetCallingAssembly(), ".Resources." + name);
}
}
}
using FirstAssembly;
namespace SecondAssembly{
public static class B
{
public static Stream FileNameFromType(string Name)
{
return = A.OpenResource(string name);
}
}
}
and Test project method
using SecondAssembly;
namespace ThirdAssembly{
public class TestC
{
[TestMethod()]
public void StremSizTest()
{
// ARRANGE
var Stream = B.FileNameFromType("ValidMetaData.xml");
// ASSERT
Assert.IsNotNull(Stream , "The Stream object should not be null.");
}
}
}
I guess you should be able to do it like this:
using System.Diagnostics;
using System.Linq;
...
StackFrame[] frames = new StackTrace().GetFrames();
string initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.AssemblyQualifiedName
).Distinct().Last();
This will get you the Assembly which contains the first method which was started first started in the current thread. So if you're not in the main thread this can be different from the EntryAssembly, if I understand your situation correctly this should be the Assembly your looking for.
You can also get the actual Assembly instead of the name like this:
Assembly initialAssembly = (from f in frames
select f.GetMethod().ReflectedType.Assembly
).Distinct().Last();
Edit - as of Sep. 23rd, 2015
Please, notice that
GetMethod().ReflectedType
can be null, so retrieving its AssemblyQualifiedName could throw an exception.
For example, that's interesting if one wants to check a vanilla c.tor dedicated only to an ORM (like linq2db, etc...) POCO class.
This will return the the initial Assembly that references your currentAssembly.
var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
.Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
.Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();
It worked for me using this:
System.Reflection.Assembly.GetEntryAssembly().GetName()
Assembly.GetEntryAssembly() is null if you run tests from nunit-console too.
If you just want the name of the executing app then use:
System.Diagnostics.Process.GetCurrentProcess().ProcessName
or
Environment.GetCommandLineArgs()[0];
For nunit-console you would get "nunit-console" and "C:\Program Files\NUnit 2.5.10\bin\net-2.0\nunit-console.exe" respectively.
Try:
Assembly.GetEntryAssembly().ManifestModule.Name
This should be the assembly that was actually executed to start your process.
Not completely sure what you're looking for, especially as when running in the context of a unit test you'll wind up with:
mscorlib.dll
Microsoft.VisualStudio.TestPlatform.Extensions.VSTestIntegration.dll
(or something similar depending on your test runner) in the set of assemblies that lead to any method being called.
The below code prints the names of each of the assemblies involved in the call.
var trace = new StackTrace();
var assemblies = new List<Assembly>();
var frames = trace.GetFrames();
if(frames == null)
{
throw new Exception("Couldn't get the stack trace");
}
foreach(var frame in frames)
{
var method = frame.GetMethod();
var declaringType = method.DeclaringType;
if(declaringType == null)
{
continue;
}
var assembly = declaringType.Assembly;
var lastAssembly = assemblies.LastOrDefault();
if(assembly != lastAssembly)
{
assemblies.Add(assembly);
}
}
foreach(var assembly in assemblies)
{
Debug.WriteLine(assembly.ManifestModule.Name);
}
If you know the number of frame in the stack, you can use the StackFrame object and skip the number of previous frame.
// You skip 2 frames
System.Diagnostics.StackFrame stack = new System.Diagnostics.StackFrame(2, false);
string assemblyName = stack.GetMethod().DeclaringType.AssemblyQualifiedName;
But, if you want the first call, you need to get all frames and take the first. (see AVee solution)
How about Assembly.GetEntryAssembly()? It returns the main executable of the process.
Process.GetCurrentProcess().MainModule.ModuleName should also return about the same as the ManifestModule name ("yourapp.exe").
This works for getting the original assembly when using two assemblies in an NUnit test, without returning a NULL. Hope this helps.
var currentAssembly = Assembly.GetExecutingAssembly();
var callerAssemblies = new StackTrace().GetFrames()
.Select(x => x.GetMethod().ReflectedType.Assembly).Distinct()
.Where(x => x.GetReferencedAssemblies().Any(y => y.FullName == currentAssembly.FullName));
var initialAssembly = callerAssemblies.Last();

Using dynamic in C# to access field of anonymous type - possible?

I've got a controller method:
public JsonResult CalculateStuff(int coolArg)
{
if(calculatePossible)
return Json(CoolMethod(coolArg));
else return Json(new { Calculated = false });
}
Now, I'd like to test this.
public void MyTest
{
var controller = GetControllerInstance();
var result = controller.CalculateStuff().Data as dynamic;
Assert.IsTrue(result.Calculated == false);
}
This throws a RuntimeBinderException saying that Calculated is not defined. Is there any way to achieve this?
UPDATE
Following Jons' advice, I used InternalsVisibleTo to befriend my test assembly. Everything works fine. Thank you Jon.
You can do it, but only within the same assembly. The anonymous type is internal.
It should also be okay if you use InternalsVisibleTo in your production assembly to grant access to your test assembly though.

Categories